if constexpr 在模板中的用法

jmc*_*mcd 1 c++ constexpr c++17 if-constexpr

我试图了解 if constexpr 的实用程序,并想知道以这种方式使用它是否有任何实用程序。

template<bool B>
int fun()
{
    if constexpr (B)
        return 1;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这个函数是否通过使用 if constexpr 而不是常规 if 进行了根本改变?我认为性能是一样的。我对模板的理解是 if 语句的结果在编译时就已经知道,所以没有区别。

max*_*x66 5

的效用constexpr

一个简单的例子...如果您编写以下函数

template <typename T>
auto foo (T const & val)
{
   if ( true == std::is_same_v<T, std::string>> )
      return val.size()
   else
      return val;
}
Run Code Online (Sandbox Code Playgroud)

并用一个整数来调用它

foo(42);
Run Code Online (Sandbox Code Playgroud)

你会得到一个编译错误,因为指令

val.size();
Run Code Online (Sandbox Code Playgroud)

也必须在valis时实例化int,但不幸的是,int不是具有size()方法的类

但如果你constexpr在之后添加if

// VVVVVVVVV
if constexpr ( true == std::is_same_v<T, std::string>> )
   return val.size()
Run Code Online (Sandbox Code Playgroud)

现在,该return val.size();指令T在is时实例化std::string,因此您也可以使用foo()参数调用而不使用size()方法。

- - 编辑 - -

正如@prapin 在评论中观察到的那样(谢谢!),if constexpr对于函数来说可能是必需的auto

我提出另一个简单(而且愚蠢)的例子

如果没有if constexpr,则以下bar()功能

template <typename T>
auto bar (T const &)
{
   if ( true == std::is_same_v<T, std::string>> )
      return 42;
   else
      return 42L;
}
Run Code Online (Sandbox Code Playgroud)

无法编译,因为第一个return返回一个int值,第二个返回一个long; 因此,鉴于if constexpr编译器必须实例化两个returns,因此编译器无法协调returns 类型,也无法确定函数的返回类型。

if constexpr

   if constexpr ( true == std::is_same_v<T, std::string>> )
      return 42;
   else
      return 42L;
Run Code Online (Sandbox Code Playgroud)

编译器实例化第一个return 第二个;两者都不会。因此编译器会确定从函数返回的类型(int当使用 a 调用时std::stringlong否则)。

  • 另外,正如您的示例实际上表明的那样,使用“auto”返回类型,使用“if constexp”,每个分支都可以返回*不同的*类型,这对于普通的“if”来说是不可能的。 (2认同)