C ++概念:CRTP

时间:2016-11-28 20:40:30

标签: c++ c++-concepts

可能只是概念很糟糕,但我不明白为什么。并没有找到任何构造函数的例子。或者它可能与构造函数无关......

template < typename T >
concept bool C_Object() {
  return requires {

    T();
  };
}

template < C_Object Object>
class  DefaultManager {

  //  Content;
};

template < C_Object Derived >
class  Component {

  // Content
};

struct Test : public Component<Test> {

  int data;

  Test() = default;
};

int main() {

  Test test;
  return 0;
}

给出错误:

test2.cpp:21:36: error: template constraint failure
 struct Test : public Component<Test> {
                                    ^
test2.cpp:21:36: note:   constraints not satisfied
test2.cpp:2:14: note: within ‘template<class T> concept bool C_Object() [with T = Test]’
 concept bool C_Object() {
              ^~~~~~~~
test2.cpp:2:14: note: the required expression ‘T()’ would be ill-formed

这听起来像是:“嘿,我的代码坏了,请修好”,抱歉。

无论如何,谢谢

度过美好的一天

2 个答案:

答案 0 :(得分:5)

问题在于:

struct Test : public Component<Test> {

无论何时 name 是约束类模板的特化,都会根据约束验证给定的参数。在这种特殊情况下,这意味着检查C_Object<Test>是否满意,但由于Test不完整 - 编译器尚未解析其定义 - C_Object不满意。

这是CRTP基础的经典问题的“概念”版本:您必须延迟检查派生类,直到其定义完成。

答案 1 :(得分:0)

我发现最易读的选项是返回类型受限的“ impl”方法。让我们以Luc Danton's comment中的示例为例,并将其传输到C ++ 20:

template <typename Var>
concept Fooable = requires(Var var) {
  {var.foo()};
};

template <typename Derived>
struct mixin {
  void bar() { impl().foo(); }
  Fooable auto& impl() { return static_cast<Derived&>(*this); } // Constrain return here!
};

// no constraint violation
struct ex1 : mixin<ex1> {
  void foo() {}
};

// no violation either
struct ex2 : mixin<ex2> {};

int main() {
  // mixin<ex1>::bar constraints respected
  ex1{}.bar();

  // mixin<ex2>::bar constraints violation
  ex2{}.bar();
}
相关问题