2016-12-05 10 views
1

для функцииназначения перегруженной функции для работы указателя в качестве значения по умолчанию

foo(int (*fnptr)(int)); 

Я хочу поставить значение по умолчанию для функции указателя int bar(int)

т.е. значения по умолчанию указателя является bar

bar также перегружен как

double bar (double); 
bool bar (bool); 

как я могу присвоить значение ??

Я попытался

foo (int (*fnptr)(int) = bar); 

, но он не работает.

EDIT Я использую MS Visual Studio и получаю код ошибки C2440

'аргумент по умолчанию': не удается преобразовать из 'перегруженной-функции' до 'Error_C (__cdecl *) (HMstd :: исключение)'

Моя текущая функция является членом класса я определен exception пространства имен HMstd

virtual Error_C execute_protocol(Error_C(*execute)(exception ex) = HMstd::MErr); 

И функция

Error_C MErr(Error_C code); 
Error_C MErr(char* desc); 
Error_C MErr(exception ex); 

где Error_C другой класс

Это определение три перегруженной функции HMstd::MErr является

Error_C HMstd::MErr(Error_C code) 
{ 
    std::cout << "\n\nError: An Error Of Code " << int(code) << "  Occured....\n\n"; 
    return SUCCESS; 
} 

Error_C HMstd::MErr(char* desc) 
{ 
    if (desc == NULLPTR) 
     return E_NULLPTR; 
    std::cout << desc; 
    return SUCCESS; 
} 

Error_C HMstd::MErr(exception ex) 
{ 
    bool Nullar = TRUE; 
    bool uninit; 
    for (int i = 0;i < 200;i++) 
     if (ex.description[i] != '\0') 
      Nullar = FALSE; 
    uninit = (int(ex.code) == -201) && Nullar; 
    if (uninit) 
    { 
     return UNINIT_PARAMETER; 
    } 
    MErr(ex.code); 
    MErr(ex.description); 
    return SUCCESS; 
} 
+2

Какая ошибка вы получаете? Мне это хорошо. – Quentin

+1

У меня нет проблем с компиляцией такого кода. Не могли бы вы предоставить [MCVE] (http://stackoverflow.com/help/mcve)? Какой компилятор/версия/платформа вы используете? – Holt

+0

Yup. 'int bar (int); двойной бар (двойной); bool bar (bool); void foo (int (* fnptr) (int) = bar); int main() {} 'компилируется и работает для меня. –

ответ

2

БЫСТРЫЙ ОТВЕТ:

Используйте тип отливка

SHORT КОД:

// ... 
int bar (int) { 
    cout << "Right\n"; 
    // bar(true); // just in case you want to invoke bool bar(bool) 
    // bar(0.0f); 
    return 0; 
} 
// ... 
int foo (int (*ptr) (int) = static_cast<int (*) (int)>(bar)) { 
    return ptr(0); 
} 
// ... 

ПОЛНЫЙ КОД:

#include <iostream> 

using namespace std; 

int bar (int) { 
    cout << "Right\n"; 
    // bar(true); // just in case you want to invoke bool bar(bool) 
    // bar(0.0f); 
    return 0; 
} 

bool bar (bool) { 
    return false; 
} 

double bar (double) { 
    return 0; 
} 

int foo (int (*ptr) (int) = static_cast<int (*) (int)>(bar)) { 
    return ptr(0); 
} 

int main() { 
    return foo(); 
} 

Explaination:

У вас есть более чем один bar, так что я не могу поставить = bar в качестве параметра по умолчанию. Из-за этого вы должны указать, какой bar. Я использовал тип-литье, поэтому компилятор может указать один из этих bar.Я видел, что вы предоставляете только два bardouble bar(double), но вы не можете преобразовать ни одну из этих функций в int bar(int) (если gcc позволяет это, программа, возможно, работает некорректно, особенно с double bar(double)), поэтому вам нужно вызвать один из этих двух в новый int bar(int)

Примечание:

Вы также можете использовать небезопасным типа литья C-Style (int (*)(int)) bar вместо static_cast<int (*) (int)>(bar) но это C++

Если вы используете Turbo C++, код выше, вероятно, не будет работать, поэтому вы можете предпочесть C-style-casting или просто переключиться на GCC.

ТАКЖЕ:

How do I specify a pointer to an overloaded function?

+1

в C++ лучше использовать 'static_cast' –

+0

Я боюсь' static_cast' быть «слишком продвинутым» для такого простого вопроса. Во всяком случае, я его обновлю. – DMaster

+3

well 'static_cast' здесь еще более адекватен, так как он удерживает нас от того, чтобы делать что-то, что может вызвать UB :) –

1

Может быть, вы ищете что-то вроде этого:

#include <iostream> 
#include <functional> 

double bar (double) { 
    std::cout << "double bar (double) called" << std::endl; 
    return 0.0; 
} 
bool bar (bool) { 
    std::cout << "bool bar (bool) called" << std::endl; 
    return false; 
} 

void foo(std::function<int(int)> fn = [](int p) -> int{ return bar(static_cast<double>(p)); }) { 
    fn(2); 
} 

int main() { 
    foo(); 
} 

Выход:

двойной бар (двойной) называется

[live demo]

вы также можете заменить использование в std::function с указателем на функцию, если вы хотите от:

void foo(int (*fn_ptr)(int) = +[](int p) -> int{ return bar(static_cast<double>(p)); }) { 
    fn_ptr(2); 
} 

[live demo]

+0

Я только что начал смотреть на лямбда-функции. я не могу понять код очень жаль – WARhead

0

Ответ был очень прост. Я объявил функцию

Error_C MErr (exception ex); 

после объявления класса exception

поэтому функция виртуального члена класса exception не может использовать эту конкретную перегрузку функции MErr я не имею возможностей реализовать параметр по умолчанию.