简体   繁体   中英

How to define a class template with reference type template parameter of template template parameter type

I would like to define a class template (hereafter called C ) which takes a reference to an object of an to-be instantiated class template (hereafter called S ) as template parameter. The objective is that C can be fully instantiated with one template argument.

S is a class template on its own which has one integral type template parameter. The C class template shall be instantiated using a reference to an object of any instantiation of S .

This is what I am trying to achieve:

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();
}

The compiler I am using supports GNU++11 or older.

There is no way that I know in C++11 that will allow you to change just the template parameters to do what you want. What you can do though is not have a non-type template parameter, but just a type, and add a constructor to C that takes the reference to the desired object as a parameter:

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

Then you could declare c as follows:

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

However, it is of course not so nice to have to repeat yourself like that, so the trick is to make a templated function that will construct a C of the right type for you:

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

And then you can write:

auto c = make_C(s);

In C++17, you might do

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 .

Before C++17, template <auto& n> struct C; has to be replaced. for example by

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

This is not the answer. But maybe this helps somebody who stumbled upon this question or even help somebody to actually find the answer.

In contrast to the original question I added the static member variable Si .

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();
}

This is not the answer, because still two template arguments are required in order to instantiate the class template C .

This compiles with C++11 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM