如何标记 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]
已知解决方案:- 不工作:如果我将经典的
(void)arr;
添加到函数中,我得到error: body of constexpr function ‘...‘ not a return-statement
。 - 不满意:我可以有
arraySize(T (&)[N])
,但我想命名的论点有两个原因:- 使编译器错误信息更容易理解。 更主观地说,我认为它使代码更清晰,特别是对于那些不生活和呼吸这种语法的人。
- 不太好:在这个特殊的例子中,我也可以
return sizeof(array)/sizeof(array[0]);
,但这种方法不是通用的解决方案,而且我认为return N;
更好,绝对更容易看。 - 好,但并不总是可能的:切换到使用c++ 14和完全支持它的编译器。然后允许像
{ (void)array; return N; }
这样的constexpr函数体。
当使用c++ 11时,我如何很好地摆脱未使用的参数警告?
试试这个。我有时使用这个方法
template <typename T, std::size_t N>
constexpr std::size_t arraySize(T (& /*array*/ )[N]) noexcept { return N; }
我建议下面(ab)使用逗号操作符:
return (void)array, N;
新用户:
c++ 17增加了[[maybe_unused]]
属性,可以这样使用:
template <typename T, std::size_t N>
constexpr std::size_t arraySize(T (&array)[N] [[maybe_unused]]) noexcept { return N; }
最佳解决方案是第二点所禁止的,即使用T(&)[N]
。
return array ? N : N;
我很确定编译器会摆脱它,在运行时不会有性能问题。
正如@fnc12和@skypjack都指出的那样,沉默未使用的参数编译器警告的惯用方法是不给参数命名。
constexpr std::size_t arraySize(T (& /*array*/ )[N]) noexcept { return N; }
使用/**/
注释解决了可读性问题。它不会在编译器消息中修复名称,但我认为最有可能出现的情况是"未声明的标识符",一旦您注意到标识符被注释,这很容易解决。
如果你真的非常反对这种习惯的方式,那么就直接取消警告(如果你的编译器允许的话)。
在GCC中使用#pragma GCC diagnostic
.
使用#pragma warning suppress
在Visual Studio中抑制警告
我建议不要在代码中添加"虚拟"引用来关闭编译器。引用一个未被使用的参数只是为了抑制编译器的警告,这不必要地增加了代码的复杂性,并且可能会使未来的维护者对它的存在感到困惑。
gcc提供了未使用的属性,可以这样使用:
constexpr std::size_t arraySize(__attribute__((unused)) T (&array)[N]) noexcept { return N; }
^^^^^^^^^^^^^^^^^^^^^^^
Ben Deane最近发了一条关于c++ 11使用lambdas和逗号操作符来抑制此警告的方法,它看起来像这样:
#define UNUSED(x) [&x]{}()
//...
return UNUSED(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);
}
相关文章:
- 仅当一个参数中未使用 std::function 时,模板函数替换才有效
- isPalindrome不显示输出,isPalindrome函数未使用字符串输入作为字符串参数进行测试
- "(void) cast"与功能有什么区别 "__attributes__"来沉默未使用的参数警告?
- 具有未使用的模板参数的函数模板
- 参数设置但未使用
- 未使用模板类型定义的同时参数包扩展错误
- 警告:用两个参数构造函数返回对象时,表达结果未使用
- clang:警告:编译期间未使用的参数:"-stdlib=libc++"
- 命令行参数未存储(使用 boost)
- C++:错误:成员访问不完整的类型,未使用的参数[-Werror,-Wunused-parameter]
- 运算符++:引用与值返回和未使用的参数
- 在C++中,是否可以使用定义中未使用的模板参数声明模板结构?
- 如何强制MSVC链接一个未使用的静态库(相当于GC——整个归档参数)
- 调试代码并C++未使用的参数警告
- C++:未使用参数优化的力度
- 是否允许类模板的函数签名模板参数中使用未展开的参数包?(可能的VS2013错误)
- 用于未使用参数参考的单线解决方案
- 函数调用中未使用的参数的模板参数推导
- 如何标记 constexpr 函数的参数未使用?
- 即使参数未使用,创建对象时是否"locked"内存空间?