检查布尔模板参数时摆脱“条件表达式为常数”警告的方法?
Posted
技术标签:
【中文标题】检查布尔模板参数时摆脱“条件表达式为常数”警告的方法?【英文标题】:Ways to get rid of "conditional expression is constant" warning when checking bool template parameter? 【发布时间】:2015-02-06 22:43:32 【问题描述】:当使用 /W4 (MSVC 2013) 编译时,此代码模板会产生“条件表达式为常量”警告:
#include <iostream>
template <bool condition>
struct Conditional
static void f()
if (condition)
std::cout << "true";
else
std::cout << "false";
;
void main()
Conditional<false>::f();
现在,假设Conditional
实际上是一个有用的类,它有很多方法和条件周围的大量代码。我想通过尽可能少的代码修改来消除警告。
我知道的唯一一个技巧是标签调度。这是可以接受的,但有点笨拙,因为我需要声明 2 个额外的方法并在那里提取条件代码。还有其他方法吗?
【问题讨论】:
标签调度听起来有点矫枉过正。您是说模板专业化吗? 我在 Java 中解决这个问题的方法是我有一个全局可见的静态get
函数,它接受任何东西作为参数并原封不动地返回它。因此,代码将如下所示:if( get( condition ) ) ...
由于编译器不知道函数是如何工作的,它不再将条件视为常量。你不能在 C++ 中做类似的事情吗?
@DrewDormann:我的意思是标签调度;专业化看起来确实非常适合这种情况。
@MikeNakis:我可以,但真的很难看!
我很想打赌它一定是替代品中最不丑的。您可以将其包装在一个宏中,该宏在编译发布时扩展为参数本身(无函数调用)。
【参考方案1】:
你可以使用专业化:
template <bool condition>
struct Conditional
static void f();
;
template <>
void Conditional<true>::f() std::cout << "true";
template <>
void Conditional<false>::f() std::cout << "false";
Live example
【讨论】:
可能是一个愚蠢的问题,但如果bool
不是唯一的模板参数,我仍然可以这样做,对吧?那将是部分专业化?如果f()
是非静态虚拟方法,它仍然可以正常工作吗?
实际上,如果特化是显式特化,您只能将方法与特化定义内联。否则(如果是部分的)你必须先定义类的特化,然后再改变方法。
^ 因为函数没有部分特化【参考方案2】:
在 C++17 及更高版本中,if constexpr
解决了这个问题:
#include <iostream>
template <bool condition>
struct Conditional
static void f()
if constexpr (condition) // No warning because the branch is calculated
// at compile time and not present at runtime.
std::cout << "true";
else
std::cout << "false";
;
void main()
Conditional<false>::f();
【讨论】:
以上是关于检查布尔模板参数时摆脱“条件表达式为常数”警告的方法?的主要内容,如果未能解决你的问题,请参考以下文章
Scala 2.12.2 发出大量无用的“警告:参数值...在方法中...从未使用过”警告。如何摆脱它们?
尝试使用router.history.goBack与react-router时获得警告