gpt4 book ai didi

c++ - SFINAE 代码检测是否为某个类型实现了 operator<< 在 Clang 和 gcc 上的行为不同

转载 作者:行者123 更新时间:2023-12-03 10:04:31 24 4
gpt4 key购买 nike

这个问题在这里已经有了答案:





Narrowing int to bool in SFINAE, different output between gcc and clang

(1 个回答)


10 个月前关闭。




我只是在玩一些 SFINAE 代码,但我无法让它工作。我正在使用带有 -std=c++17 的 Xcode 12.2。
Godbolt 表明,无论如何,Clang 确实会选择 false_type 变体,而如果两个模板参数相同并且实现了运算符,gcc 将使用 true_type 变体,正如我所期望的那样。请参阅下面的代码:

#include <iostream>
#include <type_traits>

struct MyStruct {};

std::ostream& operator<<(std::ostream& os, const MyStruct&) {
return os;
}

template<typename T, typename U = void>
struct has_ostream_operator : std::false_type {};

template<typename T>
struct has_ostream_operator<T, typename std::enable_if_t<sizeof(std::declval<std::ostream&>() << std::declval<T>()), T>> : std::true_type {};

int main() {

constexpr bool res = has_ostream_operator<MyStruct, MyStruct>::value;
if constexpr(res) {
std::cout << "Yes";
} else {
std::cout << "No";
}
return 0;
}
有人可以向我解释这里发生了什么以及为什么 Clang 和 gcc 的行为会有所不同吗?我已经使用不同的技术解决了这个问题,所以这仅用于教育目的:-)

最佳答案

如果更换整个sizeof42 构建, 两个编译器都会给你一个关于如何 sizeof 的错误不是 bool并且不能缩小为一。
如果您将其替换为 1 ,没有错误(因为 1 显然可以缩小为 true )。
考虑到这一点,让我们通过一个 bool明确地:

template<typename T>
struct has_ostream_operator<
T,
typename std::enable_if_t<
sizeof(std::declval<std::ostream&>() << std::declval<T>()) != 0,
// ^^^^^
T
>
> : std::true_type {};
现在它起作用了。
两种实现都给了我 272sizeof(std::declval<std::ostream&>() << std::declval<MyStruct>()) ,所以只是他们在 SFINAEness 期间以不同的方式处理这个错误。我认为是 GCC bug 57891 .

关于c++ - SFINAE 代码检测是否为某个类型实现了 operator<< 在 Clang 和 gcc 上的行为不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65188192/

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