将std :: enable_if与匿名类型参数一起使用 [英] Using std::enable_if with anonymous type parameters
问题描述
我尝试将 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屋!