我在声明使用boost::enable_if
的函数时遇到了一些麻烦:下面的一段代码给了我一个编译错误:
// Declaration
template <typename T>
void foo(T t);
// Definition
template <typename T>
typename boost::enable_if<boost::is_same<T, int> >::type foo(T t)
{
}
int main()
{
foo(12);
return 0;
}
编译时,我收到“模糊调用foo”错误。根据{{1}}的定义,当条件为真时,'type'typedef对应enable_if
,所以据我所知,void
的两个签名匹配。为什么编译器认为它们不同,是否有正确的方法来转发声明foo
(最好不重复foo
部分)?
答案 0 :(得分:3)
这不仅是enable_if的问题。使用以下代码在Visual Studio和gcc上得到相同的错误:
struct TypeVoid {
typedef void type;
};
template<typename T>
void f();
template<typename T>
typename T::type f() {
}
int main()
{
f<TypeVoid>();
return 0;
}
我认为主要问题是返回类型(实例化之前)是模板函数签名的一部分。有更多信息here。
关于你的代码,如果声明引用了定义,你应该同时匹配:
// Declaration
template <typename T>
typename boost::enable_if<boost::is_same<T, int> >::type foo(T t);
// Definition
template <typename T>
typename boost::enable_if<boost::is_same<T, int> >::type foo(T t)
{
}
如果声明引用了不同的函数,编译器将永远无法为 int 选择正确的函数,因为它们都是有效的。但是,您可以使用 disable_if 禁用 int 的第一个:
// Other function declaration
template <typename T>
typename boost::disable_if<boost::is_same<T, int> >::type foo(T t);
// Defition
template <typename T>
typename boost::enable_if<boost::is_same<T, int> >::type foo(T t)
{
}
答案 1 :(得分:1)
问题是声明和定义不匹配。
解决方案是声明应包含完全相同的签名和enable_if
位。
#include <boost/type_traits/is_same.hpp>
#include <boost/utility/enable_if.hpp>
// Declaration
template <typename T>
typename boost::enable_if<boost::is_same<T, int> >::type foo(T t);
// Definition
template <typename T>
typename boost::enable_if<boost::is_same<T, int> >::type foo(T t)
{
}
int main()
{
foo(12);
return 0;
}
这在VC2008上编译得很好。