【发布时间】:2021-02-18 14:03:24
【问题描述】:
代码:
#include <iostream>
using std::nullptr_t;
template<typename... T>
using nullptr_vt = nullptr_t;
struct not_addable{};
template<
typename T,
nullptr_vt<decltype(std::declval<T>() + std::declval<T>())> TSfinae = nullptr>
bool test_addable(int)
{ return true; }
template<typename>
bool test_addable(...)
{ return false; }
int main()
{
std::cout << std::boolalpha;
std::cout << test_addable<int>(0) << std::endl;
std::cout << test_addable<not_addable>(0) << std::endl;
// Gives error ("invalid operands to binary expression"):
// nullptr_vt<decltype(std::declval<not_addable>() + std::declval<not_addable>())> a{};
}
我以为这会打印出来:
true
false
,但事实并非如此。它打印:
true
true
。至少在https://repl.it/@Hrle/sfinaetemplatesuccess 上。
我认为第一个重载中的nullptr_vt<decltype(std::declval<T>() + std::declval<T>())> 对not_addable 来说是一个错误,它会从重载集中丢弃它,从而选择第二个重载。
如果有默认值,编译器是否有能力丢弃TSfinae的类型?
【问题讨论】:
-
如果我不得不冒险猜测一下,那将是那里使用的编译器(我无法访问它自己查看),无法解析issue mentioned here。并尝试在旧版本的 Clang 上修复建议的方法,wandbox.org/permlink/8pOrfXpPj0nQA4Of
-
fwiw,我可以用 gcc 重现你的结果,但 clang 是
true falsegodbolt.org/z/KjdecT -
在 gcc 上,如果您将
decltype(std::declval<T>() + std::declval<T>())> TSfinae = nullptr修改为decltype(std::declval<T>() + std::declval<T>())>* TSfinae = nullptr它可以工作...