简体   繁体   中英

C++ evaluating an expression it shouldn't

I have overidden the operator| to act as a filter for a given vector and a function, if this function returns a bool . In case it doesn't, it calls for_each on the vector .

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;
  }
}

This code works fine when acting as a filter, but the for_each part is broken. Whenever I try to run the following code:

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

The compiler 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...
                                        ^

Which seem strange to me, after all, the compiler shoudn't be executing that line in the second operator, as result should be false . Can anyone help me on this one?

This lambda:

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

has a void return type, so this line:

bool func_return = f(*itr);

doesn't compile. Since the value of result depends only on Func and T , you have the necessary information to decide whether to execute the if branch at compile time. You can use a constexpr if instead of a run-time if :

if constexpr(result)

and now the code inside this branch will not be compiled when the function is instantiated with the wrong types.

Also, you need to make result a compile time constant to use it in a if constexpr condition.

Here's a demo .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM