L0r*_*en2 3 c++ c++-concepts c++20
我想创建一个通用print(x)函数,它对于不同类型有不同的行为。
到目前为止,我所拥有的适用于所有容器类型,包括我自己编写的容器类型。然而,要么调用了“错误”的函数,要么由于不明确而无法编译。
这是我的代码:
#include <iostream>
#include <concepts>
class Container
{
int x, y, z;
public:
Container(int a, int b, int c) : x(a), y(b), z(c) {}
Container() : x(0), y(0), z(0) {}
std::size_t size() const { return 3; }
const int& operator[] (std::size_t index) const { if(index == 0) return x; else if(index == 1) return y; else return z; }
int& operator[] (std::size_t index) { if(index == 0) return x; else if(index == 1) return y; else return z; }
};
template<typename T>
concept printable_num = requires (T t, std::size_t s)
{
{ t.size() } -> std::convertible_to<std::size_t>;
{ t[s] } -> std::same_as<int&>;
};
template<printable_num T>
void print(const T& t) {
std::size_t i = 0;
for(;i < t.size() - 1; i++)
std::cout << t[i] << ", ";
std::cout << t[i] << std::endl;
}
template<typename T>
concept printable = requires (T t, std::size_t s)
{
{ t.size() } -> std::convertible_to<std::size_t>;
{ t[s] } -> std::convertible_to<char>;
};
template<printable T>
void print(const T& t) {
std::size_t i = 0;
for(;i < t.size() - 1; i++)
std::cout << t[i];
std::cout << t[i] << std::endl;
}
int main()
{
Container c{1, 2, 3};
print(c);
Container empty;
print(empty);
std::string s{"this is some string"};
print(s);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如您所见,如果返回的类型operator[]是,我想打印分隔符int&。由于不明确,这不会编译。
有没有一种方法可以进行编译并让我到达我想要的位置(对于 std::string 调用不带分隔符的打印函数,对于我自己的容器类型调用带有分隔符的打印函数)?
给定一个整数(或一的左值),您是否同意它可以转换为 a char?这些约束准确地检查了您让它们检查问题中的类型的内容。
解决这个问题的一种方法是通过约束包含。这意味着(以非常手波浪的方式),如果您的概念被编写为相同基本约束的共轭(或析取),则编译器可以规范化表达式以选择“更专业的表达式”。将其应用到您的示例中..
template<typename T>
concept printable = requires (T t, std::size_t s)
{
{ t.size() } -> std::convertible_to<std::size_t>;
{ t[s] } -> std::convertible_to<char>;
};
template<typename T>
concept printable_num = printable<T> && requires (T t, std::size_t s)
{
{ t[s] } -> std::same_as<int&>;
};
Run Code Online (Sandbox Code Playgroud)
请注意我们过去如何printable定义printable_num“更具体”的概念。运行这个例子,我们得到你想要的输出。
| 归档时间: |
|
| 查看次数: |
718 次 |
| 最近记录: |