'Can I access a non-type template class argument from outside? How?

Please check the following code:

#include <iostream>

template <int Size>
class Test
{
  public:
    // Will not compile, if Size is not a type!
    // error: 'Size' does not name a type
    using MySize = Size;
    double array[Size];
};

using MyTestArray = Test<3>;

int main()
{
    MyTestArray testArray;

    std::cout << "Test array has size " << MyTestArray::MySize << std::endl;

    return 0;
}

Is there any possibility to access Size from outside without introducing a boilerplate getter like this?

constexpr static int getSize() 
{
    return Size;
}


Solution 1:[1]

You can define a constexpr static variable with the value of the template parameter inside the class, for example

template <int Size>
class Test
{
  public:
    constexpr static auto MySize = Size;
    double array[Size];
};

Then you access like this

using MyTestArray = Test<3>;
auto size =  MyTestArray::MySize;

Solution 2:[2]

You can also use the decltype specifier assuming a constness of the MySize variable. An example similar to the above post.

#include <iostream>

using namespace std;

template <int Size>
class Test
{
public:
    static const decltype(Size) MySize = Size;
    double array[Size];
};

using MyTestArray = Test<3>;

int main()
{
    MyTestArray testArray;

    std::cout << "Test array has size " << MyTestArray::MySize << std::endl;

    return 0;
}

Solution 3:[3]

You'll need some boilerplate. Either add a static member to Test or if you do not want that or if you cannot modify Test you can use a type trait:

#include <iostream>

template <int Size> class Test {};

template <typename T> struct MySize;
template <int Size> struct MySize<Test<Size>> { static constexpr const int value = Size; };
template <typename T> constexpr const int MySize_v = MySize<T>::value;

int main()
{  
    std::cout << MySize_v<Test<3>>;
}

Solution 4:[4]

template <auto compile_time_known_parameter>
struct data
{
  static constexpr auto value = compile_time_known_parameter;
};

int main() { return data<64>::value; }
static constexpr auto value = compile_time_known_parameter;

static tells the compiler the storage must be in static memory

constexpr tells the compiler this is known at compile-time

auto tells the compiler to deduse the type automatically

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 康桓瑋
Solution 2 Ilian Zapryanov
Solution 3
Solution 4