将std :: enable_if与匿名类型参数一起使用 [英] Using std::enable_if with anonymous type parameters

查看:102
本文介绍了将std :: enable_if与匿名类型参数一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试将 std :: enable_if 与未使用且未命名的类型参数一起使用,以免扭曲返回类型。但是,以下代码无法编译。

I try to use std::enable_if with an unused and unnamed type parameter, in order to not distort the return type. However, the following code does not compile.

#include <iostream>

template <typename T, typename = std::enable_if_t<!std::is_integral<T>::value>>
T foo() { std::cout << "non-integral" << std::endl; return T(); }

template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
T foo() { std::cout << "integral" << std::endl; return T(); }

int main() {
  foo<float>();
  foo<int>();
}

编译器说:

7:3: error: redefinition of 'template<class T, class> T foo()'
4:3: note: 'template<class T, class> T foo()' previously declared here
 In function 'int main()':
11:12: error: no matching function for call to 'foo()'
11:12: note: candidate is:
4:3: note: template<class T, class> T foo()
4:3: note: template argument deduction/substitution failed:

这里有什么问题?我如何更改代码才能进行编译?教科书探索现代C ++明确鼓励使用带有匿名类型参数的 std :: enable_if

What is the problem here? How do I have to change the code to get it compile? The text book "Discovering Modern C++" explicitly encourages the use of std::enable_if with anonymous type parameters.

编辑:我知道,如果我将 std :: enable_if 放入返回类型,它将起作用。但是,我的目的是获得更多详细信息,如果我将其与匿名类型参数一起使用,为什么它不起作用。如我所说,我的课本鼓励使用匿名类型参数的变量,所以我想知道为什么我的代码无法编译。

I know that it works if I put std::enable_if into the return type. However, my intention is to get some more details why it does not work if I use it with anonymous type parameters. As I said, my text book encourages the variant using anonymous type parameters, so I am wondering why my code does not compile.

推荐答案


但是,我的目的是获得更多详细信息,如果我将其与匿名类型参数一起使用时为何不起作用。

However, my intention is to get some more details why it does not work if I use it with anonymous type parameters.

默认值不参与重载解析,因此您实际上是在重新定义相同的函数。

Default values do not participate in overload resolution, thus you are actually redefining the same function.

让我们简化您的示例:

template<typename = int>
void f() {}

template<typename = void>
void f() {}

int main() {
    f<>();
}

上面的代码无法编译,因为它不知道哪个版本 f 您要调用。

The code above does not compile, for it couldn't know what version of f you want to invoke.

在您的情况下,如果我调用 foo foo< void,void> ,我遇到了几乎相同的问题。

编译器无法猜测我的意图,并且第二个参数具有默认值的事实并不意味着您不能传递其他类型。

In your case, if I invoke foo as foo<void, void>, I've almost the same problem.
The compiler cannot guess what's my intention and the fact that the second parameter has a default value doesn't mean that you can't pass in a different type.

因此,代码格式错误且

另外,您仍然可以在不使用<$的情况下使它工作。 c $ c> std :: enable_if_t 作为返回类型。

例如:

As a side note, you can still have it working without using the std::enable_if_t in the return type.
As an example:

#include <type_traits>
#include <iostream>

template <typename T, std::enable_if_t<!std::is_integral<T>::value>* = nullptr>
T foo() { std::cout << "non-integral" << std::endl; return T(); }

template <typename T, std::enable_if_t<std::is_integral<T>::value>* = nullptr>
T foo() { std::cout << "integral" << std::endl; return T(); }

int main() {
    foo<float>();
    foo<int>();
}






出OP的(错误)假设是什么,并解释为什么会这样,@ TC

值得引用他的评论以为答案添加更多详细信息:


While I tried to figure out what was the (wrong) assumption of the OP and explain why it can be the case, @T.C. correctly pointed the attention out to the actual reason in the comments to this answer.
It's worth to quote his comment to add more details to the answer:

这不是重载解析;它是声明匹配的。首先,不会出现两个歧义,因此不会产生任何歧义。这是两个重新定义错误:函数模板和默认模板参数。

It's not overload resolution; it's declaration matching. There are no two overloads in the first place for any ambiguity to arise. It's two redefinition errors: the function template, and the default template argument.

这篇关于将std :: enable_if与匿名类型参数一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆