gpt4 book ai didi

c++ - 确保具有 C++20 概念的类方法

转载 作者:行者123 更新时间:2023-12-03 07:03:22 25 4
gpt4 key购买 nike

我喜欢 Java 中的接口(interface)特性,并期待新的 C++20 标准,引入概念。
在当前的项目中,我将对同一件事进行多种实现。其余代码应该不受此影响,并以一般“一刀切”的方式处理它们。此外,为了帮助其他人编写代码自己实现这个可交换部分,我希望有一个文档的中心位置,描述所有需要的部分。
我试着让它工作了一段时间,但我一直在与 C++20 概念作斗争。由于没有什么真正起作用,我用一个小例子描述了我想要的东西:

/* Should have a element type, like float, int, double, std::size_t,... */
template <typename Class>
concept HasElementType = requires {
typename Class::Element;
};

/* Central place for the documentation: in the concept.
* Since all relevant parts should be listed here, they can be documentated.
*/
template < typename Class, typename T>
concept HasFunctions = requires {
Class::Class(int); /* has constructor with int */
T Class::field; /* has field with name "field" of type T */
int Class::foo(T); /* has method foo, taking T, returning int */
T Class::bar(int); /* has method bar, taking int, returning T */
void Class::foobar(); /* has method foobar, taking void, returnung void */
};

/* put both togetter */
template <typename Cls>
concept MyInterface = HasElementType<Cls> && HasFunctions<Cls,typename Cls::Element>;
以上概念 MyInterface应该确保通过 my_function<MyObject>() 调用下面的函数应该适用于不同的实现 MyObject{Implementaion1, Implementaion2,...} .
/* Some example function */
template<MyInterface MyObejct>
void my_function(){
using T = MyObejct::Element;
T t = 5;
MyObejct myObject(1);
T field = 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{});
    }
    使用概念,您基本上可以为一组需求命名。如果一个概念很长,你不需要一直重复它。

    关于c++ - 确保具有 C++20 概念的类方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64761720/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com