mkmostafa
mkmostafa

Reputation: 3171

C++ template inheritance hides template parameters

template <typename>
struct B
{
    constexpr static int T = 5;
};

template <int T>
struct D : B<int>
{
    constexpr static int value = T;
};

int main()
{
    std::cout << D<7>::value << std::endl; // 5, how to get 7 ?
}

Demo

As I have recently learned that the template parameters of a template derived class get checked after the names in the base class during lookup. That being said, is there anyway to qualify the name T initializing value to refer to the template parameter T of the derived class?

EDIT:

So far from discussions in the comments it seems that the only way to achieve this is by making the base class type/value dependent which will delay the lookup to the names of the base (to the instantiation phase) and thus making the only available value for T is the template parameter.

Upvotes: 12

Views: 365

Answers (3)

George Sovetov
George Sovetov

Reputation: 5238

To refer to value T of template B (which doesn't depend on B's template parameter):

#include <iostream>

template <typename>
struct B
{
    constexpr static int T = 5;
};

template <int T>
struct D : B<decltype(B<void>::T)>
{
    constexpr static int value = T;
};

int main()
{
    std::cout << D<7>::value << std::endl;
}

To refer type of template parameter T of template D:

#include <iostream>

template <typename>
struct B
{
    constexpr static int T = 5;
};

template <int T>
struct D : B<decltype(T)>
{
    constexpr static int value = T;
};

int main()
{
    std::cout << D<7>::value << std::endl;
}

Upvotes: 0

Alan Birtles
Alan Birtles

Reputation: 36488

I'm not entirely sure I understand the question but I think decltype does what you want:

template <int T>
struct D : B<decltype(T)>
{
    constexpr static decltype(T) value = T;
};

Upvotes: 8

Rakete1111
Rakete1111

Reputation: 49018

Because B is template, you can modify it to make it a dependent base class of D:

template <typename, int = 0>
struct B {
    constexpr static int T = 5;
};

template <int T>
struct D : B<int, T> {
    constexpr static int value = T; // name lookup of base T is deferred
};

Upvotes: 1

Related Questions