【问题标题】:overloaded function with no contextual type information没有上下文类型信息的重载函数
【发布时间】:2017-09-02 18:22:02
【问题描述】:
#include<iostream>
#include<stdio.h>
#include<string.h>

using namespace std; 

void cb(int x)
{
    std::cout <<"print inside integer callback : " << x << "\n" ;    
}

void cb(float x)
{
    std::cout <<"print inside float callback :" << x <<  "\n" ;
}

void cb(std::string& x)
{
    std::cout <<"print inside string callback : " << x << "\n" ;
}

int main()
{

void(*CallbackInt)(void*);
void(*CallbackFloat)(void*);
void(*CallbackString)(void*);

CallbackInt=(void *)cb;
CallbackInt(5);

CallbackFloat=(void *)cb;
CallbackFloat(6.3);

CallbackString=(void *)cb;
CallbackString("John");

return 0;

}

上面是我的代码,它有三个函数,我想创建三个回调,它们将根据它们的参数调用重载函数。 CallbackInt 用于调用 cb 函数,以 int 为参数,其余两个类似。

但是用它编译时会出现如下错误。

 function_ptr.cpp: In function ‘int main()’:
 function_ptr.cpp:29:21: error: overloaded function with no contextual type information
 CallbackInt=(void *)cb;
                 ^~
 function_ptr.cpp:30:14: error: invalid conversion from ‘int’ to ‘void*’ [-fpermissive]
 CallbackInt(5);
          ^
 function_ptr.cpp:32:23: error: overloaded function with no contextual type information
 CallbackFloat=(void *)cb;
                   ^~
 function_ptr.cpp:33:18: error: cannot convert ‘double’ to ‘void*’ in argument passing
 CallbackFloat(6.3);
              ^
 function_ptr.cpp:35:24: error: overloaded function with no contextual type information
 CallbackString=(void *)cb;
                    ^~
 function_ptr.cpp:36:24: error: invalid conversion from ‘const void*’ to ‘void*’ [-fpermissive]
 CallbackString("John");

【问题讨论】:

  • 为什么有函数指针参数void*? --> void(*CallbackInt)(int);
  • 为什么会有这些演员表? -> CallbackInt=&amp;cb;(@FilipKočica 修改后)
  • 最好用重载的operator () 编写调用包装器。如果您需要将回调存储在单独的变量中,那么您需要正确声明函数指针类型而不是void (void*);
  • 您在程序中出现了六次void*,出现次数过多。
  • 永远不要写这么糟糕的代码。避免在 C++ 程序中进行 C 风格转换。此外,你们所有的回调都定义不正确。如果它们被正确定义,您将不需要演员表。事实上,大量演员表通常表明代码编写不佳。 阅读专家撰写的 C++ 书籍以正确学习语言。

标签: c++ c++11 function-pointers


【解决方案1】:

1) 编译器不知道选择cb 的哪个重载。
2) 即使它知道,它也不会在没有任何显式转换的情况下从void* 转换为void(*)(int)

但是,如果你给编译器足够的信息,它可以推断出来:

void cb(int x)
{
    std::cout <<"print inside integer callback : " << x << "\n" ;
}

void cb(float x)
{
    std::cout <<"print inside float callback :" << x <<  "\n" ;
}

void cb(const std::string& x)
{
    std::cout <<"print inside string callback : " << x << "\n" ;
}

int main()
{

    void(*CallbackInt)(int);
    void(*CallbackFloat)(float);
    void(*CallbackString)(const std::string&);

    CallbackInt = cb;
    CallbackInt(5);

    CallbackFloat = cb;
    CallbackFloat(6.3);

    CallbackString = cb;
    CallbackString("John");

    return 0;

}

【讨论】:

    【解决方案2】:

    我知道这是一篇旧帖子,但我最近收到了这个错误,我的问题是我没有声明我将函数结果设置为的变量。不知道为什么这个错误是它针对该问题给出的错误,但希望这对某人有所帮助。

    【讨论】:

      【解决方案3】:

      对于第一个错误,使用静态转换来指定你想要的重载,比如here

      对于其余部分,您不能有意义地将 int 或 float 强制转换为 void*。不知道你想在这里做什么。

      CallbackInt 应该带一个 int 参数...

      【讨论】:

      • 如果函数指针变量类型设置正确,则无需使用任何类型转换。
      • 没错,但我不确定 OP 想要做什么。
      猜你喜欢
      • 2021-10-02
      • 1970-01-01
      • 2019-08-16
      • 2012-03-07
      • 2023-03-21
      • 2014-04-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多