转发声明一个使用enable_if:模糊调用的函数

时间:2010-01-08 17:14:58

标签: c++ forward-declaration ambiguity enable-if

我在声明使用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部分)?

2 个答案:

答案 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上编译得很好。