【问题标题】:C++ concepts: Some signatures function conversionC++ 概念:一些签名函数转换
【发布时间】:2016-11-30 11:59:30
【问题描述】:

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

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

CFoo --> 类 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

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

祝你有美好的一天

【问题讨论】:

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


    【解决方案1】:

    我知道这不会编译,因为 Foo 没有 get menber […]

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

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

    Addable&lt;int, long&gt; 被满足,因为给定int lhs; long rhs; 那么lhs + rhs 是一个有效的表达式。我们在参数列表中显式引入的两个(假装)变量上使用内置加法运算符,而不是在隐式 *this 上调用成员 operator+

    概念是关于广义上的接口(如“API”),而不是狭义的 OOP。您可以将Addable 视为类型对的关系。 Addable&lt;int, long&gt; 持有并不意味着 int 本身与 Addable 有特殊关系。 Addable 确实可以用作例如

    template<Addable<long> Var>
    struct client {
        Var var;
    };
    

    然后client&lt;int&gt; 带有Addable&lt;int, long&gt; 约束,但这个快捷方式本质上是语法。这是一种减少样板文件的有用方法,即让我们不用写template&lt;typename Var&gt; requires Addable&lt;Var, long&gt;

    考虑到这一点,这里有一些可能接近于检查您提到的成员签名的表达式,以及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 场景,因为它值得单独提问,这里是lead。)

    【讨论】:

    • 你说得对,我对概念和类视而不见。非常感谢。如果您认为 Foo5 超出范围,我会尝试并关闭问题。
    猜你喜欢
    • 1970-01-01
    • 2018-12-16
    • 1970-01-01
    • 1970-01-01
    • 2013-06-19
    • 1970-01-01
    • 2021-03-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多