C ++概念:一些签名功能转换

时间:2016-11-30 11:59:31

标签: c++ templates variadic-templates c++-concepts

不幸的是,我发现的关于concepts的唯一教程是概念精简教程(它非常基础)。即使有技术规范,也有一些签名功能,我不知道如何转换成概念(可能只是因为我的英语很糟糕,我不能很好地阅读技术规范)。

所以有一个签名功能列表我仍然不知道如何“翻译”:

CFoo - > class CFoo {};

  • void Foo1() const;
  • CFoo& Foo2();
  • void Foo3(CFoo&);
  • {static, friend, ... } void Foo4();
  • template < typename ... Args > void Foo5(Args && ... args);

我希望为具有这些功能的类提供某种界面。 甚至不知道在这一点上是否可能。 Foo2和Foo3似乎是同样的问题。

老实说,我真的很想知道Foo2和Foo5。

我为Foo2尝试了一些事情,但我对Foo5一无所知:

class Handle {};

template < typename Object >
concept bool C_Object =
  requires(Handle handle) {
    {get(handle)} -> Object&
  };

template < C_Object Object >
class Foo {

  Object obj;
};

int main() {

  Foo<int>  test;
  return 0;
}

我知道这不会编译,因为Foo没有get menber,但这些不是正确的错误:

Test1.cpp:6:16: error: there are no arguments to ‘get’ that depend on a template parameter, so a declaration of ‘get’ must be available [-fpermissive]
     {get(handle)} -> Object&
                ^
Test1.cpp:6:16: note: (if you use ‘-fpermissive’, G++ will accept your code, but allowing the use of an undeclared name is deprecated)
Test1.cpp: In function ‘int main()’:
Test1.cpp:18:10: error: template constraint failure
   Foo<int>  test;
          ^
Test1.cpp:18:10: note:   constraints not satisfied
Test1.cpp:4:14: note: within ‘template<class Object> concept const bool C_Object<Object> [with Object = int]’
 concept bool C_Object =
              ^~~~~~~~
Test1.cpp:4:14: note:     with ‘Handle handle’
Test1.cpp:4:14: note: the required expression ‘get(handle)’ would be ill-formed

如果有人可以指出一些资源,或者为什么不给我一个解决方案。会很棒。

度过美好的一天

1 个答案:

答案 0 :(得分:2)

  

我知道这不会编译,因为Foo没有得到一个结果[...]

概念处理正常表达式。特别是,requires表达式的范围是正常范围,而不是类范围。这个概念可能更明显:

template<typename Lhs, typename Rhs>
concept bool Addable = requires(Lhs lhs, Rhs rhs) {
    lhs + rhs;
};

Addable<int, long>已完成,因为给定int lhs; long rhs;lhs + rhs是有效的表达式。我们在参数列表中明确引入的两个(假装)变量上使用内置加法运算符,而不是在隐式operator+上调用成员*this

概念是关于更广泛意义上的接口(如&#39; API&#39;),而不是更窄的OOP意义。您可以将Addable视为对类型的关系。 Addable<int, long>持有int并不代表AddableAddable有特殊关系。确实template<Addable<long> Var> struct client { Var var; }; 可以用作例如。

client<int>

然后Addable<int, long>带有template<typename Var> requires Addable<Var, long>约束,但此快捷方式本质上是语法。这是一种减少样板的有用方法,即使我们免于撰写Handle

考虑到这一点,这里有一些表达式可能会接近检查您提到的成员签名,加上template<typename Obj> concept bool Object = requires(Obj obj, Obj const cobj, Handle handle) { cobj.Foo1(); { obj.Foo2() } -> Obj&; obj.Foo3(obj); // static Obj::Foo4(); // non-member, possibly friend Foo4(obj); { obj.get(handle) } -> Obj&; }; 场景:

Foo5

(我忽略了Element方案,因为它值得自己提出问题,这里是lead。)