如何将 constexpr 函数的参数标记为未使用?

How to mark a constexpr function's parameter unused?

考虑这个经典示例:

template <typename T, std::size_t N>
constexpr std::size_t arraySize(T (&array)[N]) noexcept { return N; }

现在这个工作正常,但有一个烦恼,gcc 给出警告:

warning: unused parameter ‘array’ [-Wunused-parameter]

已知解决方案:

如何在使用 C++11 时很好地消除未使用参数警告

最好的解决方案是第二点禁止的,即使用T(&)[N]

根据评论,另一种可能的方法是使用以下 return 值:

return array ? N : N;

我很确定编译器会摆脱它并且在运行时不会有性能问题。

试试这个。我有时用这个方法

template <typename T, std::size_t N>
constexpr std::size_t arraySize(T (& /*array*/ )[N]) noexcept { return N; }

正如@fnc12 和@skypjack 所指出的,消除未使用参数编译器警告的惯用方法是不给参数命名。

constexpr std::size_t arraySize(T (& /*array*/ )[N]) noexcept { return N; }

使用 /**/ 注释解决了可读性问题。它没有修复编译器消息中的名称,但我认为最有可能由此产生的情况是 "undeclared identifier",一旦您注意到标识符已被注释,这很容易解决。

如果您真的坚决反对惯用的方式,那么只需取消警告(如果您的编译器允许,则在本地)。

Suppressing warnings in GCC using #pragma GCC diagnostic.

Suppressing warnings in Visual Studio using #pragma warning suppress

我建议不要在代码中添加 "dummy" 引用来关闭编译器。除了抑制编译器警告外,无缘无故地引用一个未使用的参数会不必要地增加代码的复杂性,并且会使未来的维护者困惑为什么它在那里。

我建议逗号运算符的以下(滥用)用法:

return (void)array, N;

未命名的参数是正确的解决方案。

所以你可以使用一个中间函数:

template <typename T>
constexpr void avoid_warning_for_unused_parameter(T&&) noexcept{}

然后:

template <typename T, std::size_t N>
constexpr std::size_t arraySize(T (&array)[N]) noexcept
{
    avoid_warning_for_unused_parameter(array);
    return N;
}

对于 C++11,您还需要再破解一点:

template <typename... Ts>
constexpr auto return_first_and_avoid_warning_for_unused_parameters(T&&t, Ts&&) noexcept
-> decltype(t)
{
    return t;
}

template <typename T, std::size_t N>
constexpr std::size_t arraySize(T (&array)[N]) noexcept
{
    return return_first_and_avoid_warning_for_unused_parameters(N, array);
}

gcc 提供了unused attribute,可以按如下方式使用:

constexpr std::size_t arraySize(__attribute__((unused)) T (&array)[N]) noexcept { return N; }
                                ^^^^^^^^^^^^^^^^^^^^^^^

Ben Deane recently tweatted about a C++11 way 使用与逗号运算符结合的 lambda 来抑制此警告,如下所示:

#define UNUSED(x) [&x]{}()

//...

return UNUSED(array), N;

对于新的 google 员工:

C++17 添加了一个 [[maybe_unused]] 属性,可以这样使用:

template <typename T, std::size_t N>
constexpr std::size_t arraySize(T (&array)[N] [[maybe_unused]]) noexcept { return N; }