【问题标题】:Work around disregarded constexpr in Visual Studio?在 Visual Studio 中解决忽略的 constexpr?
【发布时间】:2019-10-28 04:10:26
【问题描述】:

我有这个代码:

constexpr int log2(const unsigned int x) {
    return x < 4 ? 1 : 1 + log2(x / 2);
}

int main() {
    bitset<log2(2)> foo;
    int bar[log2(8)];

    cout << log2(8) << endl;
}

这在 gcc 中运行良好:https://ideone.com/KooxoS

但是当我尝试 时,我得到了这些错误:

错误 C2975:_Bitsstd::bitset 的模板参数无效,预期的编译时常量表达式
注意:见_Bits的声明
错误 C2131:表达式未计算为常量
注意:失败是由于调用了未定义的函数或未声明的函数constexpr
注意:查看log2的用法

显然log2constexpr,所以我认为这只是 中的一个错误。有没有办法解决这个错误?

【问题讨论】:

  • 看起来像视觉工作室问题。尝试使用 Visual Studio 2019,因为它们在标准合规性方面通常稍有落后。
  • 如果我将其重命名为 log22(或 Log2),它会在 VS2017 中编译,我得到的只是warning C4101: 'bar': unreferenced local variable,输出打印为 3。看起来它选择了一个不是 constexpr 的标准库?
  • @NathanOliver 这是一个糟糕的重复我可以在本地得到相同的编译错误没有 using namespace std;
  • @Borgleader 很棒的评论。就是这个问题,谢谢。我很快就会接受其中一个答案。

标签: visual-studio-2017 visual-studio-2017 c++ c++11 visual-studio-2017 constexpr compile-time-constant


【解决方案1】:

看起来您的项目包含标准的 std::log2 函数,编译器会将其与您的 log2 函数混淆。即使您不#include &lt;cmath&gt; 也可能发生这种情况,因为标准头文件允许包含任何其他标准头文件。这也是using namespace std; 事与愿违的另一个例子。

一种解决方案是将您的 constexpr 函数重命名为其他名称:

#include <bitset>
#include <iostream>

using namespace std;

constexpr int logTwo(const unsigned int x) {
    return x < 4 ? 1 : 1 + logTwo(x / 2);
}

int main() {
    bitset<logTwo(2)> foo;
    int bar[logTwo(8)];

    cout << logTwo(8) << endl;
}

Demo

编辑:似乎using namespace std; 在这种情况下可能无关。无论如何,标准的log2 函数可能在全局命名空间中可用。

【讨论】:

    【解决方案2】:

    显然log2constexpr

    constexpr 的函数并不意味着它总是可以用于计算计算时间值。当x &gt;= 4 时,你调用的是std::log2,而不是constexpr 本身。

    GCC 将它们作为扩展来实现。见Is it a conforming compiler extension to treat non-constexpr standard library functions as constexpr?

    【讨论】:

    • 我还要补充一点,名称冲突是由于使用命名空间而发生的
    • @GuillaumeRacicot Allegedly that's not true...
    • @MaxLanghof 哦,是的,我忘了数学函数也可能驻留在全局命名空间中
    猜你喜欢
    • 2014-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-18
    • 2017-04-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多