缩小 C++ 概念以排除某些类型
Narrowing down a C++ concept to exclude certain types
假设我想为 ostream
和所有容器重载左移运算符。
这是我目前拥有的(使用 -fconcepts
编译):
#include <vector>
#include <iostream>
template<typename Container>
concept bool Iterable = requires(Container t) {
{ *t.begin()++, t.end() };
};
template<Iterable T>
std::ostream& operator<<(std::ostream& out, const T& t) {
for(const auto& it: t) {
out << it << " " ;
}
return out;
}
int main() {
std::vector<int> a = {1, 2, 3};
std::cout << a << std::endl;
std::string str = "something";
// std::cout << str << std::endl; // compile error if the template is defined
return 0;
}
但是,问题是 std::string
的 ostream&<<
版本已经存在。
是否有通用的(类似于 requires not
表达式)或特定的(可能类似于部分专业化,通过它我可以排除具体 类)的方法来排除概念中的某些内容?
如果不是,正确的解决方法是什么?
template<Iterable T>
requires !requires(std::ostream o, T a) { operator<<(o, a); }
std::ostream& operator<<(std::ostream& out, const T& t) {
for(const auto& it: t) {
out << it << " " ;
}
return out;
}
添加类型尚未定义 operator<<
的要求。我不是 100% 确定这应该有效,但它确实适用于 gcc。
(只是 o << a
使 gcc 崩溃)
假设我想为 ostream
和所有容器重载左移运算符。
这是我目前拥有的(使用 -fconcepts
编译):
#include <vector>
#include <iostream>
template<typename Container>
concept bool Iterable = requires(Container t) {
{ *t.begin()++, t.end() };
};
template<Iterable T>
std::ostream& operator<<(std::ostream& out, const T& t) {
for(const auto& it: t) {
out << it << " " ;
}
return out;
}
int main() {
std::vector<int> a = {1, 2, 3};
std::cout << a << std::endl;
std::string str = "something";
// std::cout << str << std::endl; // compile error if the template is defined
return 0;
}
但是,问题是 std::string
的 ostream&<<
版本已经存在。
是否有通用的(类似于 requires not
表达式)或特定的(可能类似于部分专业化,通过它我可以排除具体 类)的方法来排除概念中的某些内容?
如果不是,正确的解决方法是什么?
template<Iterable T>
requires !requires(std::ostream o, T a) { operator<<(o, a); }
std::ostream& operator<<(std::ostream& out, const T& t) {
for(const auto& it: t) {
out << it << " " ;
}
return out;
}
添加类型尚未定义 operator<<
的要求。我不是 100% 确定这应该有效,但它确实适用于 gcc。
(只是 o << a
使 gcc 崩溃)