MSVC 抱怨函数指针不是编译时常量
Posted
技术标签:
【中文标题】MSVC 抱怨函数指针不是编译时常量【英文标题】:MSVC complaining that function pointer is not a compile time constant 【发布时间】:2012-08-11 21:17:05 【问题描述】:我正在尝试获取一些最初使用 GCC 构建的代码以使用 MSVC 进行编译,并且在代码中遇到了回调包装类的问题。我提取了以下代码的关键部分:
template <typename T_func>
struct internal_parameter_resolver;
template <typename R>
struct internal_parameter_resolver<R()>
typedef R(*type)();
;
template <typename R, typename P1>
struct internal_parameter_resolver<R(P1)>
typedef R(*type)(P1);
;
template <typename T_func, typename internal_parameter_resolver<T_func>::type func>
void bind()
// Create and return instance of class Callback...
double func1() return 0.5;
int func2(double i) return 0;
int main()
bind<double(), &func1>(); // (Line 23)
bind<int(double), &func2>(); // (Line 24)
return 0;
虽然在 GCC 下可以正常编译,但 MSVC 2010 会给出以下错误消息:
1>c:\users\public\documents\projects\_test\_test\main.cpp(23): error C2975: 'func' : invalid template argument for 'bind', expected compile-time constant expression
1> c:\users\public\documents\projects\_test\_test\main.cpp(14) : see declaration of 'func'
1>c:\users\public\documents\projects\_test\_test\main.cpp(24): error C2975: 'func' : invalid template argument for 'bind', expected compile-time constant expression
1> c:\users\public\documents\projects\_test\_test\main.cpp(14) : see declaration of 'func'
有人知道为什么 MSVC 认为这些函数指针不是编译时常量吗?还是代码中其他地方的问题(即不是第 23 和 24 行)?如果这是编译器中的错误,我欢迎任何有关可能解决方法的建议。
谢谢!
【问题讨论】:
使用 gcc 4.6 && clang 3.1 编译良好。 @mfontanini 是的,我知道,是 MSVC 给我带来了问题。 【参考方案1】:template <typename T_func, T_func* >
void bind()
// Create and return instance of class Callback...
Visual C++ 不擅长解析间接类型定义,但它对更具体的类型很满意,就像上面一样。
上面显示了如何使用 Visual C++ 处理您遇到的直接问题。
不过,更好的设计是使用自动模板参数推导:
template <typename T_func >
void bind( T_func const func )
// Create and return instance of class Callback...
double func1() return 0.5;
int func2(double i) return 0;
int main()
bind( func1 ); // (Line 23)
bind( func2 ); // (Line 24)
您可以从std::function
获取函数结果类型,如果需要,等等。
【讨论】:
哇,就这么简单(使用 T_func*)!不幸的是,我不能使用自动模板参数推导,因为回调类的实例化需要函数指针作为模板参数。谢谢!【参考方案2】:我看不出有任何理由将func1
和func2
作为非类型模板参数传递。
最好将它们作为参数(而不是模板参数)传递,并让internal_parameter_resolver
trait 推断其类型:
template <typename T_func>
struct internal_parameter_resolver;
template <typename R>
struct internal_parameter_resolver<R()>
typedef R(*type)();
;
template <typename R, typename P1>
struct internal_parameter_resolver<R(P1)>
typedef R(*type)(P1);
;
template <typename T_func>
void bind(typename internal_parameter_resolver<T_func>::type func)
// Create and return instance of class Callback...
double func1() return 0.5;
int func2(double i) return 0;
int main()
bind<double()>(func1); // (Line 23)
bind<int(double)>(func2); // (Line 24)
return 0;
我手头没有 VC,但应该可以编译。
【讨论】:
感谢您的建议,不幸的是,回调类的实例化需要函数指针作为模板参数(它基于codeproject.com/Articles/136799/… 中描述的轻量级回调)。以上是关于MSVC 抱怨函数指针不是编译时常量的主要内容,如果未能解决你的问题,请参考以下文章