【问题标题】:Why this template constexpr function doesn't compile on gcc but works well on clang?为什么这个模板 constexpr 函数不能在 gcc 上编译但在 clang 上运行良好?
【发布时间】:2014-10-24 09:26:58
【问题描述】:

正如您在此处看到的 http://melpon.org/wandbox/permlink/vJSyO14mkbH0MQRq 这不会在 gcc 上编译并出现错误:

prog.cc: In instantiation of 'constexpr B convert(A) [with A = unsigned char; B = short unsigned int]':
prog.cc:16:52:   required from here
prog.cc:12:1: error: body of constexpr function 'constexpr B convert(A) [with A = unsigned char; B = short unsigned int]' not a return-statement

代码:

#include <stdint.h>
#include <limits>
#include <iostream>

template< typename A, typename B >
constexpr B convert( A a )
{
    auto aMax = std::numeric_limits< A >::max();
    auto bMax = std::numeric_limits< B >::max();

    return a * ( bMax / aMax );
}

int main()
{
    std::cout << convert< uint8_t, uint16_t >( 128 ) << std::endl;
    return 0;
}

【问题讨论】:

    标签: c++ gcc clang c++14


    【解决方案1】:

    此代码需要一个名为“放松对 constexpr 函数的约束”的 C++14 功能。 Clang 从 3.4 版开始支持它,但 GCC didn't implement it yet 并随后抱怨您的函数模板。

    虽然不需要 C++14,只需将其重写为

    template <typename B, typename A> //! Note that I reordered the parameters
    constexpr B convert( A a )
    {
        return a * (std::numeric_limits< B >::max() / std::numeric_limits< A >::max());
    }
    

    您也可以使用别名声明。

    template <typename T, T v>
    using iconst = std::integral_constant<T, v>;
    
    template <typename B, typename A>
    constexpr B convert( A a )
    {
        using aMax = iconst<A, std::numeric_limits< A >::max()>;
        using bMax = iconst<B, std::numeric_limits< B >::max()>;
        return a * (bMax::value / aMax::value);
    }
    

    Demo

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-13
      • 2023-03-23
      • 1970-01-01
      • 1970-01-01
      • 2018-08-02
      • 1970-01-01
      • 1970-01-01
      • 2021-08-14
      相关资源
      最近更新 更多