我最近开始用 C++ 编程。我正在尝试学习用 c++20 表示的概念。当我在做我的作业时,我遇到了一个问题。有人能告诉为什么这不想编译吗?
它报告:
1.Error C3864 'ns1::BufferedCollection<T>': requires clause is incompatible with the declaration for each function
BufferedCollectionHeader.h
namespace ns1
{
template<typename T>
concept AddableComparable= requires (const T& a,const T& b)
{
{a + b} -> std::convertible_to<T>;
{a < b} -> std::convertible_to<bool>;
};
template<typename T>
concept Printable = requires(std::ostream stream,const T& a)
{
{stream << a} -> std::convertible_to<decltype(stream)>;
};
template<typename T>
concept AddableComparablePrintable = AddableComparable<T> && Printable<T>;
template<typename T>
requires AddableComparablePrintable<T>
class BufferedCollection : public IPrintable
{
static_assert(std::is_copy_assignable<T>::value, "Tip T nije copy_assignable");
static_assert(std::is_move_assignable<T>::value, "Tip T nije move_assignable");
int elements;
int buffers;
int capacity;
template<typename K>
struct Node
{
int capacity;
K* p;
Node<K>* next;
};
Node<T>* list;
public:
BufferedCollection(int)noexcept;
...
};
}
BufferedCollection.h
#include "BufferedCollectionHeader"
template<typename T>
requires ns1::AddableComparablePrintable<T>
ns1::BufferedCollection<T>::BufferedCollection(int n)noexcept: elements(0),buffers(0),capacity(n),list(nullptr){};
...
源.cpp
class TestClass:public ns1::IPrintable
{
int x;
public:
friend std::ostream& operator<<(std::ostream& stream, const TestClass& test)
{
stream << test.to_string();
return stream;
}
TestClass(int n):x(n){}
std::string to_string()const noexcept override
{
return std::to_string(x);
}
TestClass operator+(const TestClass& t)const
{
return TestClass(t.x + x);
}
bool operator<(const TestClass& t)const
{
return true;
}
};
int main()
{
ns1::BufferedCollection<TestClass> bc(3);
return 0;
}
注意事项:
答案 0 :(得分:0)
您不应该按价值获取数据流。它们不可复制。
friend std::ostream& operator<<(std::ostream& stream, const TestClass& test)
您需要 const 限定您的 +
和 <
,因为约束看起来是 const T &
TestClass operator+(const TestClass& t) const;
bool operator<(const TestClass& t) const;
旁白:你为什么要为only +
、<<
和 <
定义一个概念? std::three_way_comparable
有什么问题?
为什么是 static_assert
可分配性,而不是概念?
答案 1 :(得分:0)
concept Printable = requires(std::ostream stream,const T& a)
应该得到一个引用作为输入(在朋友定义中也是如此!):
template<typename T>
concept Printable = requires(std::ostream &stream,const T& a)
^~~~~~~
{
{stream << a} -> std::convertible_to<decltype(stream)>;
};
除此之外,您的 TestClass
的加法和比较运算符应标记为 const
。如果你改变它,它编译正常:live demo。我进一步简化了您的示例并将其放入单个文件中。因此,我不确定这是否能解决您的所有问题。
更新
从这个 comparison 可以看出,GCC 和 clang 编译但 MSVC 仍然拒绝代码。