C++ C++;20个概念要求运算符重载与用户定义模板运算符重载功能相结合 案例1

C++ C++;20个概念要求运算符重载与用户定义模板运算符重载功能相结合 案例1,c++,templates,operator-overloading,language-lawyer,c++20,C++,Templates,Operator Overloading,Language Lawyer,C++20,考虑以下概念,要求范围的值类型可打印: #include <iostream> #include <iterator> template <class R, typename T = std::ranges::range_value_t<R>> concept printable_range = requires(std::ostream& os, const T& x) { os << x; }; GCC和MSVC

考虑以下
概念
要求
范围的
值类型
可打印:

#include <iostream>
#include <iterator>

template <class R, typename T = std::ranges::range_value_t<R>>
concept printable_range = requires(std::ostream& os, const T& x) { os << x; };
GCC和MSVC可以传递以下断言,但不能传递:

MSVC使用相同的断言失败,但GCC仍然会:


叮当声是正确的。这是通常的两阶段查找规则,已知GCC对操作员的处理不正确(MSVC也不知道是否支持正确的两阶段查找,尽管它们正在变得更好)

运算符的普通非限定查找
我应该信任哪个编译器?它看起来像一只叮当作响的虫子


这是一个GCC/MSVC错误。查找
os@cigien番茄、otamot等的名称。。。
static_assert(printable_range<std::vector<int>>);
std::ostream& operator<<(std::ostream& os, const auto& x) { return os << x; }
static_assert(printable_range<std::vector<std::vector<int>>>);
struct S{};
std::ostream& operator<<(std::ostream& os, const S&) { return os; }
static_assert(printable_range<std::vector<std::vector<int>>>);
void print(int x) { std::cout << x; };

template <class R, typename T = std::ranges::range_value_t<R>>
concept printable_range = requires(const T& x) { print(x); };

void print(auto x) { std::cout << x; };

static_assert(printable_range<std::vector<int>>);
static_assert(printable_range<std::vector<std::vector<int>>>); // failed!