恒定表达式在完成时起作用,而不是单个功能

Constant expression works when is done as parts but not as a single function

本文关键字:单个 功能 起作用 表达式 完成时      更新时间:2023-10-16

代码适用于A,B,A,W,但对于J.这是完全相同的代码刚刚分解。什么给?

我试图使"使"起作用作为恒定的表达。对于编译器而言,该代码在此简单示例上失败并不那么复杂。

非常奇怪...

template<typename... Args> constexpr
auto all2(Args... args) noexcept
{ return static_cast<int>((... + args)); }
struct xx
{
    int y = 2;
    constexpr operator int () const noexcept { return y; }
};
template<int C, typename... Args>
struct pepe2
{
    constexpr pepe2( Args... args ){}
};
template< typename... T_ARGS > constexpr
auto make( const T_ARGS&... args ) noexcept
{
    return pepe2< all2(args...), T_ARGS... >{};
}
int main()
{
    // This works as expected
    constexpr static xx             a   {};
    constexpr static xx             b   {};
    constexpr static auto           A   { all2( a, b ) };
    constexpr static pepe2<A,xx,xx> W   { a, b };
    // But this does not!!!
    constexpr static auto  J    = make( a, b );
    return 0;
} 

clang的实际错误

<source>:21:24: error: non-type template argument is not a constant expression
    return pepe2< all2(args...), T_ARGS... >{};
                       ^
<source>:33:35: note: in instantiation of function template specialization 'make<xx, xx>' requested here
    constexpr static auto  J    = make( a, b );

函数参数不是 constexpr。实际上,make函数可以采用非costexpr参数。因此,我们不能将它们用于模板实例化。

函数参数不是常数表达式。您可以将ab作为模板参数传递。

#include <type_traits>
template<typename... Args> constexpr
auto all2(Args... args) noexcept
{ return static_cast<int>((... + args)); }
struct xx
{
    int y = 2;
    constexpr operator int () const noexcept { return y; }
};
template<int C, typename... Args>
struct pepe2
{
    constexpr pepe2( Args... ){}
};
template< auto&... T_ARGS > constexpr
auto make() noexcept
{
    return pepe2< all2(T_ARGS...), std::decay_t<decltype(T_ARGS)>... >{T_ARGS...};
}
int main()
{
    // This works as expected
    constexpr static xx             a   {};
    constexpr static xx             b   {};
    constexpr static auto           A   { all2( a, b ) };
    constexpr static pepe2<A,xx,xx> W   { a, b };
    // This also works now
    constexpr static auto  J    = make<a, b>();
    return 0;
}