简体   繁体   中英

c++17: function template lambda specialization

Motivation: one has a function that accepts either a lambda or a value (for simplicity it can be either const char * or std::string ) like following

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
}

I'm struggling to properly implement a function Evaluate() ie to make the code below compile. In particular, which return value to use in the "value"-based implementation to preserve the type (eg const char * or 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;
}

Since you have access to C++17, why not use std::is_invocable , if constexpr and decltype(auto) combo?

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

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