在VS2017中不是编译时常量表达式

时间:2017-05-21 16:34:38

标签: c++ c++11 templates visual-studio-2017 constexpr

VS2017 15.1无法编译以下代码:

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

错误是:

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

如果我没有从Derived派生Base,则错误消失。使用gcc 5.4.0和clang 4.0.0,两种情况都可以。

这段代码有什么问题吗?

2 个答案:

答案 0 :(得分:1)

由于size是静态的,因此没有真正的理由继承Base。以下代码正在运行

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

如果您仍需要继承基地,可以执行以下操作

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

我不确定100%为什么VS不允许在继承和静态函数访问中使用相同的模板arg。当我需要它时,上面做了诀窍:)

答案 1 :(得分:0)

这是Visual Studio错误。根据Visual Studio反馈系统report,此问题已在Visual Studio 2019版本16.2中得到修复。