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

时间:2019-01-29 15:17:17

标签: c++ gcc compiler-errors metaprogramming icc

以下代码可在gcc 8.2上编译,但无法在icc 19.0.1上编译:

DECLARE
        -- Fetch the first 5 entries of the table.
        CURSOR cTableA IS
               SELECT  ColumnA, ColumnB, ColumnC
               FROM    TableA
               WHERE   ROWNUM <= 5;

        rTableA cTableA%ROWTYPE; --Not realy needed this time, but some think it is neat.
BEGIN
        FOR rTableA IN cTableA LOOP
                DBMS_OUTPUT.PUT_LINE('ColumnA: ' || rTableA.ColumnA);
                DBMS_OUTPUT.PUT_LINE('ColumnB: ' || rTableA.ColumnB);
                DBMS_OUTPUT.PUT_LINE('ColumnB: ' || rTableA.ColumnC);
        END LOOP;
END;
/

我从icc收到的错误是:

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

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

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

1 个答案:

答案 0 :(得分:0)

这不能回答我关于谁是正确的以及为什么的问题,但是这是一种(稍差些)的解决方法,可在两个编译器上使用。如果有人知道更好的解决方案,我将很高兴。

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