简体   繁体   English

在 C++ 中干净地将 void 处理为 labmda 的通用返回类型

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

I am trying to write a function like this:我正在尝试像这样编写 function :

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 .其中T有时是void The compilation (on VS2019) fails with error C2182: 'resultA': illegal use of type 'void' .编译(在 VS2019 上)失败并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).现在发生的事情是编译器仍然会编译两个if分支(因为它实际上不知道在运行时之前会调用哪个分支)。 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.这实际上只会根据 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.当 T 为 void 时,编译器将匹配重载,而不是分派到 function 的通用版本。 Here you could even say "if T is an int do something different" which is kind of neat (but can get messy).在这里你甚至可以说“如果 T 是一个int做一些不同的事情”,这有点整洁(但可能会变得混乱)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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