简体   繁体   中英

Cleanly handling void as generic return type of labmda in C++

I am trying to write a function like this:

template <typename T>
void testActionBehavesIdentically(Foo& fooA, Foo& fooB, std::function<T(Foo&)> action)
  if (std::is_same<T, void>::value)
  {
    // perform action even if T is void
    action(fooA);
    action(fooB);
  }
  else
  {
    // if T is not void, test also return values
    T resultA = action(fooA);
    T resultB = action(fooB);
    CHECK_EQUAL(resultA, resultB);
  }
  // tests that the state of both foos is the same
  CHECK_EQUAL(fooA, fooB);
}

where T is sometimes void . The compilation (on VS2019) fails with error C2182: 'resultA': illegal use of type 'void' . Is there a clean way around it? (Hopefully one that will compile in most standard compilers)? Thank you.

Right now what's happening is that the compiler still will compile both if branches (since it doesn't actually know which will be called until runtime). This results in a failure since one of the branches doesn't compile correctly. There are a couple fixes (from the comments):

If your compiler supports it this would be one option:

  if constexpr (std::is_same<T, void>::value) {
    // perform action even if T is void
    action(fooA);
    action(fooB);
  } else {
    ...
  }

this will only actually compile one branch depending on the type of T.

If your compiler doesn't support it, here's another option:

template <typename T>
void testActionBehavesIdentically(Foo& fooA, Foo& fooB, std::function<T(Foo&)> action) {
    // check assuming T != void
}

// overload which will be called if T was void
void testActionBehavesIdentically(Foo& fooA, Foo& fooB, std::function<void(Foo&)> action) {
    // check assuming T == void
}

The compiler will match the overload when T is void instead of dispatching to the generic version of the function. Here you could even say "if T is an int do something different" which is kind of neat (but can get messy).

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