2

考虑以下程序:

#include <iostream>

template<typename... Params_t>
constexpr int constexprValue(Params_t...) { return 5; }

int main()
{
    const bool flag = true;

    if constexpr(flag)
    {
        constexpr int value = constexprValue(1, 2, 3);
        std::cout << value << "\n";
    }
}

这可以编译并正常工作。但是,如果flag改为false,则 clang (Apple LLVM version 10.0.0 (clang-1000.10.44.4)) 给出编译器错误:

error: constexpr variable 'value' must be initialized by a constant expression
undefined function 'constexprValue<int, int, int>' cannot be used in a constant expression

这是clang中的错误吗?

4

2 回答 2

1

是的,这似乎是 Apple 版本的 clang 中的一个错误,我能够使用 clang 版本 5 及更高版本以及 gcc 版本 7.1 及更高版本编译代码。

Matt Godbold 有一个很棒的网站,可以使用大量不同的编译器来编译代码片段。

是您在 Godbolt 中的示例的链接。

于 2018-11-07T10:37:25.160 回答
1

是的,这是这个对 clang 的提交修复的错误:[Sema] Discarded statment 应该是一个可评估的上下文。其中有以下描述:

constexpr 评估程序出错,因为这些模板没有定义。尽管在废弃语句中使用,我们仍然需要 constexpr 评估它们,这意味着我们需要实例化它们。修复 PR37585。

差异修订:https ://reviews.llvm.org/D48322

并包括以下测试:

namespace PR37585 {
template <class T> struct S { static constexpr bool value = true; };
template <class T> constexpr bool f() { return true; }
template <class T> constexpr bool v = true;

void test() {
  if constexpr (true) {}
  else if constexpr (f<int>()) {}
  else if constexpr (S<int>::value) {}
  else if constexpr (v<int>) {}
}
}

如果我们使用较旧的 clang 版本使用 Godbolt 进行实时测试,我们会得到与您的示例非常相似的错误诊断:

error: constexpr if condition is not a constant expression
else if constexpr (f<int>()) {}
                   ^~~~~~~~

note: undefined function 'f<int>' cannot be used in a constant expression

该修复源自错误报告: constexpr if condition is not a constant expression and std::is_same

于 2018-11-07T16:52:48.940 回答