【问题标题】:Forward declaring a function that uses enable_if : ambiguous call转发声明使用 enable_if 的函数:模糊调用
【发布时间】:2010-01-08 17:14:57
【问题描述】:

我在声明一个使用 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 的模糊调用”错误。根据enable_if的定义,当条件为真时,'type' typedef对应void,所以据我所知,foo的两个签名匹配。为什么编译器会认为它们不同,有没有正确的方式转发声明foo(最好不要重复enable_if部分)?

【问题讨论】:

  • 匹配是问题,编译器无法决定要使用哪个模板。

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


【解决方案1】:

这不仅仅是 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_ifint 禁用第一个:

// 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)       
{       
}

【讨论】:

    【解决方案2】:

    问题是声明和定义不匹配。

    解决方案是声明应该包含完全相同的签名,以及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 上编译得很好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-13
      • 2020-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多