【问题标题】:C#-like generic, template type constraint in C++C++ 中的类 C# 通用模板类型约束
【发布时间】:2021-08-29 17:31:26
【问题描述】:

我有一段 C# 代码如下:

class Foo<T> where T : TClass
{
    // body
}

有什么标准方法可以在 C++ 中实现泛型类型约束

【问题讨论】:

    标签: c# c++ templates generics


    【解决方案1】:

    C++ 有std::is_base_of,可与 SFINAE(C++17 及更早版本)或需求 (C++20) 一起使用。 C++20还增加了std::derived_from的概念。

    C++17:

    #include <type_traits>
    #include <cstddef>
    
    template<class T, std::enable_if_t<std::is_base_of_v<TClass, T>, std::nullptr_t> = nullptr>
    class Foo
    {
        // Body
    };
    

    C++20:

    #include <type_traits>
    
    template<class T> requires std::is_base_of_v<TClass, T>
    class Foo
    {
        // Body
    };
    

    C++14 和 C++11 支持非常相似的行为,但语法不太简洁,例如将std::is_base_of_v&lt;TClass, T&gt; 替换为std::is_base_of&lt;TClass, T&gt;::value

    【讨论】:

    • 我对 Yakk 的解决方案有同样的疑问
    • 好收获@AyxanHaqverdili
    • nvm,非常感谢您 =))
    【解决方案2】:
    template<class T>
    requires (std::is_base_of_v<TClass,T>)
    class Foo{
    };
    

    请注意,这不是完全匹配,因为 Foo&lt;A&gt;Foo&lt;B&gt; 在 C++ 中是不相关的类型。泛型和模板在一些相似的用例中仍然具有不同的功能。

    泛型的完整模拟需要一个带有虚拟方法的基类,如果类型转换样板和派生模板覆盖并实现了我的经验中的一些细节,那么这些虚拟方法会做一堆。 (OTOH,这并不总是需要,模板做其他事情比泛型更容易)。

    【讨论】:

    • 我是否必须包含任何内容,因为“需要”会引发“缺少显式类型”的错误
    • @HungQuang 你需要开启 C++20 模式。你用的是什么编译器?或者,请参阅其他答案。
    • 是的,如果我这样做,它会起作用,谢谢你的支持
    【解决方案3】:

    在 C++ 中,我们很少使用基类来启用/禁用泛型。我认为这应该从我们对它的丑陋语法中可以看出,直到 C++20。

    Pre-C++20,你只需使用类型,如果它有你想要的一切,它应该编译得很好。错误消息不太理想,但它很简单而且很有效:

    template <class T>
    class Foo { /* ... */ };
    

    在 C++20 之后,我们有了“命名约束”的“概念”。它们类似于其他语言中的“接口”,但一切都在编译时解决。语法更好,您可以在示例中使用它们而不是基类:

    template <class T>
    concept TClass = ...;
    
    template <TClass T>
    class Foo { /* ... */ };
    

    【讨论】:

    • 是的,必须让它干净整洁,非常有帮助,谢谢
    猜你喜欢
    • 2020-07-21
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-11
    相关资源
    最近更新 更多