Evg
Evg

Reputation: 26282

Not compile-time constant expression in VS2017

VS2017 15.1 fails to compile the following code:

template<int data_size>
struct Data { };

template<int s>
struct Base
{
    static constexpr int size() { return s; }
};

template<int s>
struct Derived : Base<s>   // struct Derived
{
    Data<Base<s>::size()> data;
};

int main()
{
    Derived<1> c;
}

The error is:

error C2975: 'data_size': invalid template argument for 'Data', expected compile-time constant expression
note: see declaration of 'data_size'
note: see reference to class template instantiation 'Derived<s>' being compiled

If I do not derive Derived from Base, the error disappears. With gcc 5.4.0 and clang 4.0.0 everything is fine in both cases.

Is anything wrong with this code?

Upvotes: 14

Views: 1532

Answers (2)

Evg
Evg

Reputation: 26282

This was a Visual Studio bug. According to Visual Studio Feedback System report, it has been fixed in Visual Studio 2019 version 16.2.

Upvotes: 0

Yakir E
Yakir E

Reputation: 84

Since size is static there is no real reason to inherit from Base. The following code is working

template<int data_size>
struct Data 
{

};

template<int s>
struct Base
{
    static constexpr int size()  { return s; }
};

template<int s>
struct Derived 
{
    Data<Base<s>::size()> data;
};
int main()
{
    Derived<1> c;
}

If you still need to inherit from base you can do the following

template<int data_size>
struct Data 
{

};

template<int s>
struct Base
{
    static constexpr int size()  { return s; }
};

template<int s,int s1>
struct _Derived : Base<s>   // struct Derived
{
    Data<Base<s1>::size()> data;
};


template <int s>
using Derived = _Derived<s,s>;

int main()
{
    Derived<1> c;
}

I am not sure 100% why VS doesn't allow the same template arg to be used in the inheritance and the static function access. The above does the trick when I need it :)

Upvotes: 1

Related Questions