c++ - gcc8.2 和 (intel) icc19.0.1 之间的 constexpr 差异

标签 c++ gcc compiler-errors metaprogramming icc

以下代码在 gcc 8.2 上编译但在 icc 19.0.1 上编译失败:

#include <tuple>

template <typename Type, typename... TypeList>
constexpr size_t f(std::tuple<TypeList...> const &){
    return 0;
}

template <typename Type, typename Tuple>
size_t g(Tuple && t){
    static size_t constexpr v= f<Type>(t);
    return v;
}

size_t h(){
    std::tuple<int> tuple;
    return g<int>(tuple);
}

我从 icc 收到的错误是:

error: expression must have a constant value
static size_t constexpr v = f<Type>(t);
                            ^
note: the value of parameter "t" cannot be used as a constant

Intel 的编译器是正确的,因为“t”通常是未知的,不能用作常量。但是,仅使用在编译时已知的“t”类型(定义模板参数包“TypeList”)。

为什么这在 gcc 中允许但在 icc 中不允许?哪个编译器是正确的?

最佳答案

这并没有回答我关于谁是正确的以及为什么是正确的问题,但这里有一个(稍微不那么优雅的)解决方法,适用于两种编译器。如果有人知道更好的解决方案,我会很高兴。

template <typename Type, typename Tuple, size_t... Indices>
constexpr size_t f(std::index_sequence<Indices...> const &){
    // TypeList is now 'std::tuple_element_t<Indices, TTuple>...'
    return 0;
}
template <typename Type, typename Tuple>
constexpr size_t f(){
    using BareTuple = std::remove_const_t<std::remove_reference_t<Tuple> >;
    return f<Type, BareTuple>
        (std::make_index_sequence<std::tuple_size_v<BareTuple>>{});
}
template <typename Type, typename Tuple>
constexpr size_t g(Tuple && t){
    size_t constexpr occurrences = f<Type, Tuple>();
    return occurrences;
}
...

关于c++ - gcc8.2 和 (intel) icc19.0.1 之间的 constexpr 差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54424180/

相关文章:

c++ - 将 size_t 转换为 int 以声明 char 数组的大小

c++ - 分析 SWIG Python 代码

c++ - 枚举值与枚举名称冲突

javascript - JavaScript游戏引擎—编辑器:) ERRORS in Inspector?中的代码运行

c - 多线程 pthread 错误

c++ - 在对象已经初始化后,如何使用赋值运算符覆盖 C++ 中的类对象?

c++ - 如何在 GCC 中启用 C/C++ "Conditional with Omitted Operand"(又名 Elvis Operator "?:")

c - "comparison between signed and unsigned integer expressions"仅包含无符号整数

javac 不显示编译器错误?

c++ - 检测 2 行 opencv