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

для функции

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

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

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

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

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

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

Я пытался

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

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

ИЗМЕНИТЬ Я использую MS Visual Studio и получаю код ошибки C2440.

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

Моя фактическая функция является функцией-членом класса, который я определил 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;
} 

person WARhead    schedule 05.12.2016    source источник
comment
Какую ошибку вы получаете? Это выглядит хорошо для меня.   -  person Quentin    schedule 05.12.2016
comment
У меня нет проблем с компиляцией такого кода. Не могли бы вы предоставить MCVE? Какой компилятор/версию/платформу вы используете?   -  person Holt    schedule 05.12.2016
comment
Ага. int bar(int); double bar (double); bool bar (bool); void foo( int (*fnptr)(int)=bar); int main() {} компилируется и запускается для меня.   -  person Martin Bonner supports Monica    schedule 05.12.2016
comment
Обратите внимание, что вам нужно объявить возвращаемый тип для foo.   -  person Martin Bonner supports Monica    schedule 05.12.2016
comment
В частности, какой компилятор вы используете?   -  person Martin Bonner supports Monica    schedule 05.12.2016
comment
Работайте как положено здесь.   -  person Jarod42    schedule 05.12.2016


Ответы (3)


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

Использовать приведение типов

КОРОТКИЙ КОД:

// ...
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();
}

ПОЯСНЕНИЕ:

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

ПРИМЕЧАНИЕ:

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

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

СМОТРИТЕ ТАКЖЕ:

Как указать указатель на перегруженную функцию?< /а>

person DMaster    schedule 05.12.2016
comment
в С++ лучше использовать static_cast - person W.F.; 05.12.2016
comment
Я боюсь, что static_cast слишком продвинут для такого простого вопроса. В любом случае, я обновлю его. - person DMaster; 05.12.2016
comment
ну static_cast здесь даже более адекватен, так как удерживает нас от того, что может вызвать UB :) - person W.F.; 05.12.2016
comment
Нет ничего продвинутого в том, чтобы научиться предпочитать приведения в стиле С++. Использование стамески вместо кувалды — это то, чему все начинающие программисты должны научиться как можно скорее. - person StoryTeller - Unslander Monica; 05.12.2016
comment
@StoryTeller Вот почему я ставлю цитату/конец цитаты - person DMaster; 05.12.2016
comment
@DMaster вы предоставляете только два бара bool bar(bool) и double bar(double), я сказал также перегружен как .., это означает, что помимо int bar (int) он также перегружен как то - person WARhead; 05.12.2016
comment
@WARhead Тогда извини! Я думаю, вам все же нужно добавить int bar(int), чтобы избежать путаницы. Кроме того, если вы сделали это, но все еще получаете сообщение об ошибке, это странно! Какой компилятор вы используете и как вы вызываете свой компилятор (например, g++ main.cpp -o main)? - person DMaster; 05.12.2016
comment
@WARhead Я не знаком с API-интерфейсами Win32, скажите мне: является ли HMstd::MErr статической функцией? Каков его тип? Это макрос? - person DMaster; 05.12.2016
comment
@DMaster нет, это не Win32 API HMstd::MErr - это просто функция, которая отображает код ошибки на экране в целях отладки и во время регистрации ошибок во время выполнения. HMstd::MErr не является статической функцией. то, что вы видите, это его объявление - person WARhead; 05.12.2016
comment
@WARhead Это тоже не стандартная функция! Я думаю, вы написали это, возможно, вы захотите добавить свою функцию HMstd класса HMstd::MErr к своему вопросу. - person DMaster; 05.12.2016
comment
@DMaster Это пространство имен. Вместе с классом, для которого объявлена ​​функция execute_protocol - person WARhead; 05.12.2016
comment
Ошибка C2440 возникает во время выполнения или во время компиляции? (я тоже не знаком с VS С++) - person DMaster; 05.12.2016
comment
@WARhead Не могли бы вы добавить static перед объявлением HMstd::MErr и сказать мне, что произойдет? - person DMaster; 05.12.2016

Возможно, вы ищете что-то вроде этого:

#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();
}

Вывод:

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

[демонстрация]

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

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

[демонстрация]

person W.F.    schedule 05.12.2016
comment
я только начал смотреть на лямбда-функции. я не могу понять код очень извините - person WARhead; 05.12.2016

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

Error_C MErr (exception ex);

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

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

person WARhead    schedule 05.12.2016