【问题标题】:Not compile-time constant expression in VS2017不是 VS2017 中的编译时常量表达式
【发布时间】:2017-05-21 16:34:38
【问题描述】:

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

如果我没有从Base 派生Derived,错误就会消失。使用 gcc 5.4.0 和 clang 4.0.0 在这两种情况下一切都很好。

这段代码有什么问题吗?

【问题讨论】:

  • Data&lt;size()&gt; dataData&lt;Derived::size()&gt; data 是否出现同样的错误?
  • 如果你第一次调用并存储结果是这样的:static constexpr auto size{ Base&lt;s&gt;::size() };,你可以在之后使用它:Data&lt;size&gt; data;。这可以编译,但我不确定为什么直接将其作为模板参数不可以。
  • @melpomene Data&lt;size()&gt; 产生错误,Data&lt;Derived::size()&gt; 工作正常(但为什么?)。
  • @melpomene Data&lt;size()&gt; data 是非法的,因为在非限定查找期间未找到依赖基类的成员。但如果 MSVC 允许,我不会感到惊讶。

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


【解决方案1】:

由于大小是静态的,因此没有真正的理由从 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。当我需要它时,上面的方法可以解决问题:)

【讨论】:

    【解决方案2】:

    这是一个 Visual Studio 错误。根据 Visual Studio 反馈系统report,已在 Visual Studio 2019 版本 16.2 中修复。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-04
    • 1970-01-01
    • 2019-03-14
    • 2018-02-28
    • 2012-12-26
    • 1970-01-01
    相关资源
    最近更新 更多