为什么这个模板 constexpr 函数不能在 gcc 上编译,但在 clang 上效果很好?

Why this template constexpr function doesn't compile on gcc but works well on clang?

本文关键字:但在 编译 clang 很好 gcc constexpr 不能 函数 为什么      更新时间:2023-10-16

如您所见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;
}

此代码需要一个名为"放宽constexpr函数的约束"的C++14特性。Clang从3.4版本开始支持它,但GCC还没有实现它,随后抱怨您的函数模板。

不过,不需要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);
}

演示

相关文章: