简体   繁体   中英

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?

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 :)

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

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