【问题标题】:Deduce template parameter from concept从概念推导出模板参数
【发布时间】:2021-05-10 15:19:58
【问题描述】:

我正在学习模板和概念。我正在尝试为从类派生的类型创建一个概念,但这个类是一个模板。

template<typename T>
struct CAA{};

template<typename T, typename T2>
concept DerivedFromAA = requires() {std::derived_from<CAA<T2>,T>;};

是否可以在函数中使用这样的概念而不必明确告诉它类的模板类型?我对如何定义这样的概念的想法是错误的吗?

template<typename T>
void conceptTestFunc(DerivedFromAA<T> auto& aa)
{
}

//...

CAA<int> aa;
conceptTestFunc<int>(aa); // Without having to tell it "int"

(我正在用 Clang 编译它。)

【问题讨论】:

    标签: c++ clang c++-concepts


    【解决方案1】:

    模板不是类型。

    所以如果CAA 是一个模板,那么CAA&lt;int&gt; 就是一个类型。

    一个类型不能从模板派生,只能从另一个类型派生。这意味着必须对类型而不是模板进行检查。

    如果你想推断aa的内部类型,可以这样做。

    #include <concepts>
    
    template<typename T>
    struct CAA{};
    
    template<typename T>
    struct CBB{};
    
    template<typename T, typename T2>
    concept DerivedFromAA = std::derived_from<CAA<T2>,T>;
    
    template<template <typename> typename Outer, typename T>
    requires DerivedFromAA<Outer<T>, T>
    void conceptTestFunc(Outer<T>& aa)
    {
    }
    
    int main() {
        CAA<int> aa;
        conceptTestFunc(aa);
        CBB<int> bb;
        conceptTestFunc(bb); // This fails
    }
    

    【讨论】:

    • 太棒了!谢谢!在声明void conceptTestFunc 之前,您能否告诉我或指出任何阅读材料在这两行中发生了什么。特别是:template&lt;template &lt;typename&gt; typename Outer, typename T&gt;
    • 它叫做template template parameters。链接中有一个部分提供了更多详细信息。
    【解决方案2】:

    你可能会这样做

    template<typename T>
    concept DerivedFromAA = requires(T t) {[]<typename U>(CAA<U>&){}(t);};
    
    static_assert(DerivedFromAA<CAA<int>>);
    

    Demo

    gcc 在 requires 中不喜欢 lambda,因此您可能会在外部创建虚拟辅助函数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-14
      • 1970-01-01
      • 2022-01-22
      • 1970-01-01
      • 1970-01-01
      • 2019-11-23
      相关资源
      最近更新 更多