2012-08-11 89 views
3

我试图获得一些最初使用GCC编译与MSVC编译的代码,并且在代码中遇到了回调包装类的问题。我已经提取下面的代码的关键部分: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行)?如果这是编译器中的错误,我会欢迎任何有关可能的解决方法的建议。

谢谢!

+0

使用gcc 4.6 &&铿锵3.1编译正常。 – mfontanini 2012-08-11 21:24:07

+0

@mfontanini是的,我知道,这是MSVC给我的问题。 – zennehoy 2012-08-11 21:25:10

回答

2
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获得函数结果类型,如果你想要的,等等。

+0

哇,真的很简单(使用T_func *)!不幸的是,我不能使用自动模板参数推导,因为回调类的实例化需要函数指针作为模板参数。谢谢! – zennehoy 2012-08-11 21:51:22

1

我看不到任何理由通过func1func2作为非类型的模板参数。

这是更好地只是将它们作为参数(而不是模板参数),并让internal_parameter_resolver特征推断其类型:

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在手,但应该编译。

+0

感谢您的建议,不幸的是,回调类的实例化需要函数指针作为模板参数(它基于http://www.codeproject.com/Articles/136799/Lightweight-Generic-C- Callbacks-or-Yet-Another-Del)。 – zennehoy 2012-08-11 21:54:19