【问题标题】:How to define a class template with reference type template parameter of template template parameter type如何使用模板模板参数类型的引用类型模板参数定义类模板
【发布时间】:2021-05-03 18:26:42
【问题描述】:

我想定义一个类模板(以下称为C),它将对要实例化的类模板(以下称为S)的对象的引用作为模板参数。目标是 C 可以用一个模板参数完全实例化。

S 本身就是一个类模板,它有一个整型模板参数。 C 类模板应使用对S 任何实例化对象的引用来实例化。

这就是我想要达到的目标:

template<int I> struct S {
    int get() { return 42 + I; }
};

//        ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓  my desperate attempt
template< typename S<int I>::template & n>
struct C {
    int get() {
        return n.get();
    }
};

S<42> s;

int main()
{
    C<s> c;
    return c.get();
}

我使用的编译器支持 GNU++11 或更早版本。

【问题讨论】:

  • @PatrickRoberts 仅当参数不是引用时才会如此(无论如何,这在 C++20 之前不起作用)。
  • 这在 C++11 中看起来不可行。在 C++17 中会很简单。
  • @HolyBlackCat 提到的 C++17 的简单性:template&lt;auto &amp;n&gt; struct C {...};
  • 被旧版本的语言标准卡住真是糟透了。 ????
  • @PatrickRoberts 不会,只要参数不是 const 引用。

标签: c++ templates


【解决方案1】:

在 C++17 中,您可能会这样做

template<int I> struct S { int get() { return 42 + I; } };

template <auto& n>
struct C;

template <int I, S<I>& n>
struct C<n>
{
    int get() { return n.get(); }
};

S<42> s;

int main()
{
    C<s> c;
    return c.get();
}

Demo.

在 C++17 之前,template &lt;auto&amp; n&gt; struct C; 必须被替换。例如通过

template &lt;typename T, T&amp; n&gt; struct C;

template <typename T, T& n>
struct C;

template <int I, S<I>& n>
struct C<S<I>, n>
{
    int get() { return n.get(); }
};

S<42> s;

#define AUTO(x) decltype(x), x

int main()
{
    C<S<42>, s> c;
    // C<AUTO(s)> c;
    return c.get();
}

Demo

【讨论】:

    【解决方案2】:

    我知道在 C++11 中没有任何方法可以让您仅更改模板参数来执行您想要的操作。你可以做的不是有一个非类型模板参数,而只是一个类型,然后向C 添加一个构造函数,它将对所需对象的引用作为参数:

    template<typename T>
    struct C {
        C(T &t): t(t) {}
        int get() {
            return t.get();
        }
    private:
        T &t;
    };
    

    那么你可以声明c如下:

    C<decltype(s)> c(s);
    

    但是,必须这样重复自己当然不是很好,所以诀窍是创建一个模板函数,它将为您构造一个正确类型的 C

    template<typename T>
    C<T> make_C(T &t) {
        return C<T>(t);
    }
    

    然后你可以写:

    auto c = make_C(s);
    

    【讨论】:

      【解决方案3】:

      这不是答案。但也许这有助于那些偶然发现这个问题的人甚至帮助某人真正找到答案。

      与原来的问题相比,我添加了静态成员变量S.i

      template<int I> struct S {
          static constexpr int i = I;
          int get() { return 42 + I; }
      };
      
      template<int I, S<I>& n> struct C
      {
          int get() {
              return n.get();
          }
      };
      
      S<42> s;
      
      int main()
      {
          C<s.i, s> c;
          return c.get();
      }
      

      这不是答案,因为仍然需要两个模板参数才能实例化类模板C

      这个compiles with C++11

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-03-18
        • 1970-01-01
        • 1970-01-01
        • 2014-01-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多