【发布时间】:2023-03-13 15:04:01
【问题描述】:
当我尝试编译此代码时,我在 Visual Studio 2012 中收到以下编译器错误:
error C2440: 'default argument' : cannot convert 'void(_cdecl*)(void)' to 'void(_cdecl*)(void)'
我的代码:
namespace bar {
template<typename T> void foo();
template<> void foo<int>() {}
}
struct A {
void(*f)();
template<typename T> inline void set_func(void(*f)()=bar::foo<T>) {this->f=f;}
};
int main(void) {
A a;
a.set_func<int>();
return 0;
}
当我将 bar::foo 移动到全局命名空间时,我不再收到错误消息。谁能解释一下?
我已经编辑了上面的代码,以消除对成员函数和模板专业化的一些混淆。我还删除了 typedef,它给出了相同错误的更奇怪的版本:cannot convert 'void(_cdecl*)(void)' to 'void(_cdecl*)(void)'
【问题讨论】:
-
你的编译器坏了。也许使用
&bar::foo<T>会有所帮助,因为它消除了到函数指针的隐式转换。 -
将
bar::foo<T>更改为&bar::foo<T>无效 -
错误信息是否更多地说明了为什么无法进行转换?您可以删除 typedef 并直接指定类型吗?您是否提交过关于 MS Connect 的错误报告?
-
删除 typedef 并直接使用
void(*)()没有帮助。我将向 MS 提交错误报告,因为这似乎很不寻常。 -
我不知道这是否相关,但您正在对
bar::foo进行明确的特化,这应该在同一个命名空间中完成,例如namespace bar{template<> void foo<int>() {}}(由于bar::foo语法,我最初认为bar是一个类,因此我删除了答案)。
标签: c++ templates namespaces function-pointers default-arguments