C++ 确保使用C+类方法+;20个概念

C++ 确保使用C+类方法+;20个概念,c++,c++20,c++-concepts,C++,C++20,C++ Concepts,我喜欢Java中接口的特性,并期待着新的C++20标准,引入概念 在当前的项目中,我将为同一件事提供多个实现。代码的其余部分应该不受此影响,并以一种通用的“一刀切”方式处理它们。此外,为了帮助其他人编写这个可交换部分的自己的实现,我希望文档有一个中心位置,描述所有需要的部分 我试图让它工作了一段时间,但我一直在与C++20的概念挣扎。因为没有什么真正起作用,我用一个小例子来描述我想要的: /*应该有一个元素类型,比如float、int、double、std::size\u t*/ 模板 概念Ha

我喜欢Java中接口的特性,并期待着新的C++20标准,引入概念

在当前的项目中,我将为同一件事提供多个实现。代码的其余部分应该不受此影响,并以一种通用的“一刀切”方式处理它们。此外,为了帮助其他人编写这个可交换部分的自己的实现,我希望文档有一个中心位置,描述所有需要的部分

我试图让它工作了一段时间,但我一直在与C++20的概念挣扎。因为没有什么真正起作用,我用一个小例子来描述我想要的:

/*应该有一个元素类型,比如float、int、double、std::size\u t*/
模板
概念HasElementType=需要{
typename类::元素;
};
/*文档的中心位置:在概念中。
*由于此处应列出所有相关部分,因此可以对其进行记录。
*/
模板
概念功能=需要{
Class::Class(int);/*具有int的构造函数*/
T类::field;/*具有名为“field”的类型为T的字段*/
int类::foo(T);/*有方法foo,取T,返回int*/
T类::bar(int);/*有方法bar,取int,返回T*/
void类::foobar();/*具有方法foobar,获取void,返回void*/
};
/*把两者放在一起*/
模板
概念MyInterface=HasElementType&&HasFunctions;
上述概念应确保通过
my_function()
调用下面的函数对于不同的实现
MyObject
∈ <代码>{implementation1,implementation2,…}

/*一些示例函数*/
模板
void my_函数(){
使用T=MyObejct::Element;
T=5;
MyObejct-myObject(1);
T字段=myObject.field;
int foo=myObject.foo(t);
T bar=myObject.bar(1);
myObject.foobar();
}
关于这一点,我有3个问题:

  • 有没有可能通过概念来实现这一点
  • 这是不是看起来很干净?由于它应该通过可访问的文档来提高可读性,如果概念的代码几乎不可读,那么它就没有用处
  • 总体而言,概念是否都是正确的方法,或者是否有其他/更好的方法来实现这一点

  • 谢谢,摩洛,你问了很多问题,所以我一一回答。首先是你的“HasElement”概念

    在这里您可以看到它是如何工作的:

    #include <iostream>
    #include <type_traits>
    
    class AWithStaticElement{
    public:
        static int Element;
    };
    int AWithStaticElement::Element = 12;
    
    class AWithInstanceElement{
    public:
        int Element;
    };
    
    class AWithElementType{
    public:
        using Element = int;
    };
    
    class AWithoutElement{
    };
    
    template<typename T>
        requires std::is_member_pointer_v<decltype(&T::Element)>
    void Foo(T t)
    {
        std::cout << "Has instance Element " << t.Element << "\n";
    }
    
    template<typename T>
    requires std::is_pointer_v<decltype(&T::Element)>
    void Foo(T t) 
        
    {
        std::cout << "Has static Element " << t.Element << "\n";
    }
    
    template<typename T>
    requires requires (T t) { typename T::Element; }
    void Foo(T t)
    {
        std::cout << "Has Element type\n";
    }
    
    template<typename... T>
    void Foo(T&&... t)
    {
        std::cout << "Has no Element!\n";
    }
    
    int main()
    {
        Foo(AWithStaticElement{});
        Foo(AWithInstanceElement{});
        Foo(AWithElementType{});
        Foo(AWithoutElement{});
    }
    
    #包括
    #包括
    类AWithStaticElement{
    公众:
    静态int元素;
    };
    int AWithStaticElement::Element=12;
    类AwiInstanceElement{
    公众:
    int元素;
    };
    AWithElementType类{
    公众:
    使用元素=int;
    };
    AWithoutElement类{
    };
    模板
    需要std::is_member_pointer_v
    void Foo(T)
    {
    
    std::cout您有一个合理的想法,但这不是requires表达式的语法

    template < typename Class >
    concept HasFunctions = requires(Class c, Class::Element e) {
        Class(1);  // don't use a null pointer constant here!
        { c.field } -> std::same_as<decltype(e)>;
        { c.foo(e) } -> std::same_as<int>;
        { c.bar(1) } -> std::same_as<decltype(e)>;
        c.foobar();
    };
    
    模板
    概念HasFunctions=requires(类c,类::元素e){
    类(1);//此处不要使用空指针常量!
    {c.field}->std::与相同;
    {c.foo(e)}->std::与相同;
    {c.bar(1)}->std::与相同;
    c、 foobar();
    };
    
    请注意,不需要单独测试
    Class::Element
    :如果该类型不存在,那么原子约束将根据需要计算为
    false


    这并不像你的措辞所暗示的那样严格;从
    int
    (可能通过隐式转换、默认参数、构造函数模板等)构造类就足够了例如,它完全忽略了
    foobar
    的返回类型。然而,正如约束作者的常见建议一样,为什么您会关心
    foobar
    是否返回某个内容?如果您希望它是
    void
    ,您无论如何也不会对返回值做太多处理。通常,要求您将使用的接口(例如,您将在此处传递
    int
    ,并忽略此处的值)而不是试图描述该类型的实现。因此,您可以考虑放宽<代码> STD::SAMEYAS AS ,也许用<代码> STD::Exchange Type到.< /P>每一个StAccOfFuff.com问题。请1。是的,2。基于意见的,但对我来说似乎很好(概念命名除外)。3、基于意见的,但似乎是一个好方法,还有其他方法(根本不检查,SFANAE)“我喜欢java中接口的特性,并且期待新C++ 20标准,引入概念”“这不是概念是什么”java“接口”只是C++中的纯虚拟类。