C++ 评估它不应该的表达式

C++ evaluating an expression it shouldn't

我已经覆盖 operator| 作为给定 vector 和函数的过滤器,如果此函数 returns 为 bool。如果没有,它会在 vector.

上调用 for_each
template<typename T, typename Func>
auto operator | (const vector<T> &v, Func f){
  bool result = is_same<bool, decltype(f(v[0]))>::value;
  vector<T> temp;
  if (result){
    temp.reserve(v.size());
    for(auto itr = v.begin(); itr != v.end(); ++itr){
      bool func_return = f(*itr);
      if (func_return){
        temp.push_back(*itr);
      }
    }
    return temp;
  }
  else{
    for_each(v.begin(),v.end(),f);
    return temp;
  }
}

此代码在用作过滤器时工作正常,但 for_each 部分已损坏。每当我尝试 运行 以下代码时:

int main() {
vector<int> v1 = { 2, 9, 8, 8, 7, 4 };
v1 | []( int x ) { return x % 2 == 0; } | [] ( int x ) { cout << x << " "; };
}

编译器returns:

error: cannot initialize a variable of type 'bool' with an rvalue of type 'void'
bool func_return = f(*itr);

in instantiation of function template
      specialization 'operator|<int, (lambda at
      main.cpp:44:43)>' requested here
v1 | []( int x ) { return x % 2 == 0; } | [] ( int x ) { cou...
                                        ^

这对我来说似乎很奇怪,毕竟编译器不应该在第二个运算符中执行该行,因为 result 应该是 false。谁能帮我解决这个问题?

这个 lambda:

[] ( int x ) { cout << x << " "; }

有一个 void return 类型,所以这一行:

bool func_return = f(*itr);

不编译。由于 result 的值仅取决于 FuncT,因此您拥有必要的信息来决定是否在编译时执行 if 分支。您可以使用 constexpr if 而不是 run-time if:

if constexpr(result)

现在,当使用错误的类型实例化函数时,将不会编译该分支中的代码。

此外,您需要使 result 成为编译时间常量,以便在 if constexpr 条件下使用它。

这是一个demo