c++17:函数模板 lambda 特化

Tru*_*uLa 1 c++ lambda templates specialization c++17

动机:有一个函数可以接受 lambda 或值(为简单起见,可以是 或const char *std::string,如下所示

template <typename LambdaOrValue>
void Function(LambdaOrValue &&lambda_or_value) {
  // The idea here is to have sort of a magic that
  // evaluates a lambda if an argument is actually
  // a lambda or do nothing otherwise
  if (Evaluate(std::forward<LabmdaOrValue>(lambda_or_value)) ==
               std::string("pattern"))
    // Do something
}
Run Code Online (Sandbox Code Playgroud)

我正在努力正确实现一个功能Evaluate(),即使下面的代码编译。特别是,在基于“值”的实现中使用哪个返回值来保留类型(例如const char *std::string

#include <type_traits>
#include <iostream>

template <typename T>
decltype(std::declval<T>()()) Evaluate(T &&t) {
  return t();
}

template <typename T>
T Evaluate(T &&t) {  // <<--- What return type use here to preserve the type
  return std::forward<T>(t);
}

int main() {
  std::cout << Evaluate("test") << std::endl;
  std::cout << Evaluate([]() { return "lambda"; }) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

Osy*_*otr 7

既然您可以访问 C++17,为什么不使用std::is_invocable,if constexprdecltype(auto)组合呢?

template <typename T>
auto Evaluate(T &&t) -> decltype(auto){
    if constexpr (std::is_invocable_v<T>)
        return t();
    else
        return std::forward<T>(t);
}
Run Code Online (Sandbox Code Playgroud)