3

所以在过去的几周里,我一直在尝试用函数式编程类型的解决方案来解决 C++11 中的问题,有时我会遇到需要一个返回常量值的函数的情况。

在 Haskell 中,有一个函数

const :: a -> b -> a
const x = \_ -> x

它返回一个函数,该函数的计算结果为 const 的原始参数,无论提供什么参数。我想在 C++11 中创建类似的东西。这样的结构对于表示函数中的特殊行为很有用(发送到过滤器的常量函数 true 将保持数据完整)。这是我的第一次尝试:

template<class T>
std::function<T(...)> constF(T x) {
    return ([x](...) { return x; });
}

这会自行编译,但任何使用它的尝试都会导致不完整类型的错误。我的第二次尝试是这样的:

template<class T, class... Args>
std::function<T(Args...)> constF(T x) {
    return ([x](Args...) { return x; });
}

这更接近了,但不允许我提供任何参数,除非我明确说明它们。

auto trueFunc1 = constF(true);
auto trueFunc2 = constF<bool, int>(true);
cout << trueFunc1() << endl; //works
cout << trueFunc1(12) << endl; //doesn't compile
cout << trueFunc2(12) << endl; //works

理想情况下,正确的构造不会在 trueFunc1 和 trueFunc2 之间产生差异。

这在 C++ 中是否可行?

4

1 回答 1

5

由于 C++11 没有泛型或可变 lambda,我将编写一个仿函数模板类:

template <typename T>
// requires CopyConstructible<T>
class const_function {
  T value;
public:
  template <typename U, typename = typename std::enable_if<std::is_convertible<U,T>::value>::type>
  const_function(U&& val) :
    value(std::forward<U>(val)) {}

  template <typename... Args>
  T operator () (Args&&...) const {
    return value;
  }
};

和一个很好的类型推断包装器来制作它们:

template <typename T>
const_function<typename std::remove_reference<T>::type>
constF(T&& t) {
  return {std::forward<T>(t)};
}

在 C++1y 中,我认为简单的等价物是:

template <typename T>
auto constF(T&& t) {
  return [t{std::forward<T>(t)}](auto&&...){return t;};
}
于 2013-07-26T20:36:15.033 回答