gpt4 book ai didi

c++ - 为什么我必须调用 operator<< 作为 SFINAE 使用 void_t 的方法?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:04:51 25 4
gpt4 key购买 nike

我正在尝试定义一个 has_ostream_operator<T> SFINAE 测试,用于检查我是否可以计算出给定的类型。我让它工作,但前提是在我对 has_ostream_operator 的定义中我调用operator<<作为一种方法而不是作为中缀运算符。换句话说,这是可行的:

decltype(std::declval<std::ostream>().operator<<(std::declval<T>()))>

这不是:

decltype(std::declval<std::ostream>() << std::declval<T>())>

下面的测试用例(也可以在 http://coliru.stacked-crooked.com/a/d257d9d6e0f3f6d9 看到)。请注意,我包含了 void_t 的定义,因为我只使用 C++14。

#include <iostream>

namespace std {

template<class...>
using void_t = void;

}

template<class, class = std::void_t<>>
struct has_ostream_operator : std::false_type {};

template<class T>
struct has_ostream_operator<
T,
std::void_t<
decltype(
std::declval<std::ostream>().operator<<(std::declval<T>()))>>
: std::true_type {};

struct Foo {};

template<class X>
void print(
const X& x,
std::enable_if_t<has_ostream_operator<X>::value>* = 0)
{
std::cout << x;
}

template<class X>
void print(
const X&,
std::enable_if_t<!has_ostream_operator<X>::value>* = 0)
{
std::cout << "(no ostream operator<< implementation)";
}

int main()
{
print(3); // works fine
print(Foo()); // this errors when using infix operator version
return 0;
}

最佳答案

我假设你的“中缀”版本使用了这个表达式:

std::declval<std::ostream>() << std::declval<T>()

匹配为Foo的原因是因为第一部分,declval<ostream>()产生 ostream&& 类型的右值.这匹配一个非成员 operator<< :

template< class CharT, class Traits, class T >
basic_ostream< CharT, Traits >& operator<<( basic_ostream<CharT,Traits>&& os,
const T& value );

该重载只是转发调用:

Calls the appropriate insertion operator, given an rvalue reference to an output stream object (equivalent to os << value).

您应该直接检查。所有重载都采用 ostream通过 lvalue 引用,所以你也应该测试它:

std::declval<std::ostream&>() << std::declval<T>()

关于c++ - 为什么我必须调用 operator<< 作为 SFINAE 使用 void_t 的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32464395/

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