gpt4 book ai didi

C++ SFINAE 没有失败

转载 作者:行者123 更新时间:2023-12-03 14:31:15 30 4
gpt4 key购买 nike

代码:

#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 的类型?如果有默认值?

最佳答案

I thought that nullptr_vt<decltype(std::declval<T>() + std::declval<T>())> from the first overload would be an error for not_addable and it would discard it from the overload set, thus choosing the second overload.


这个想法实际上很好,问题仅在于 GCC 和 nullptr_vt这一行:
nullptr_vt<decltype(std::declval<T>() + std::declval<T>())> TSfinae = nullptr
在您不希望它在 GCC 10.2 上工作但在 Clang 11.0.1 上是正确的。将其更改为
nullptr_vt<decltype(std::declval<T>() + std::declval<T>())> *TSfinae = nullptr
两者都是正确的,更简单的也是正确的
typename TSfinae = nullptr_vt<decltype(std::declval<T>() + std::declval<T>())>
typename _ = decltype(std::declval<T>() + std::declval<T>())
最后是 make_void 技巧
template<typename... T> struct make_nullptr_vt { using type = nullptr_t; };

template<typename T>
using nullptr_vt = typename make_nullptr_vt<T>::type;
也修复了 GCC 上的原始版本。

关于C++ SFINAE 没有失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66261570/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com