如何使用模板模板参数类型的引用类型模板参数定义类模板

时间:2021-05-02 15:23:52

标签: c++ templates

我想定义一个类模板(以下称为 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 或更早版本。

3 个答案:

答案 0 :(得分:1)

我知道在 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);

答案 1 :(得分: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 <auto& n> struct C;。例如通过

template <typename T, T& n> 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 :(得分:0)

这不是答案。但这也许可以帮助偶然发现这个问题的人或者甚至帮助某人真正找到答案。

与原始问题相反,我添加了静态成员变量 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