转发声明使用enable_if的函数:不明确的调用

发布于 2024-08-17 02:47:31 字数 630 浏览 9 评论 0原文

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

I have some trouble forward declaring a function that uses boost::enable_if: the following piece of code gives me a compiler error:

// 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;
}

When compiling, I get an "ambiguous call to foo" error. According to the definition of enable_if, the 'type' typedef corresponds to void when the condition is true, so as far as I can see, the two signatures of foo match. Why does the compiler think they are different, and is there a correct way to forward declare foo (preferably without repeating the enable_if part)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

蛮可爱 2024-08-24 02:47:31

这不仅仅是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;
}

我认为主要问题是返回类型(实例化之前)是模板函数签名的一部分。 此处提供了更多信息。

关于您的代码,如果声明引用定义,则应将两者匹配:

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

This is not only a problem with enable_if. You get the same error on Visual Studio and gcc with the following code:

struct TypeVoid {
  typedef void type;
};

template<typename T>
void f();

template<typename T>
typename T::type f() {
}

int main()
{
  f<TypeVoid>();
  return 0;
}

I think the main problem is that the return type (before instantiation) is part of the signature of a template function. There is more information here.

Regarding your code, if the declaration refers to the definition, you should match both:

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

If the declaration refers to a different function, the compiler would never be able to choose the correct one for ints, because they both are valid. However, you can disable the first one for ints using disable_if:

// 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)       
{       
}
压抑⊿情绪 2024-08-24 02:47:31

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

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

The problem is that the declaration and the definition do not match.

The solution is that the declaration should contain the exact same signature, and the the enable_if bit.

#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;
}

This compiles fine on VC2008.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文