【问题标题】:C# style Action<T>, Func<T,T>, etc in C++0xC++0x 中的 C# 样式 Action<T>、Func<T,T> 等
【发布时间】:2010-04-22 03:50:17
【问题描述】:

C# 具有通用函数类型,例如 Action&lt;T&gt;Func&lt;T,U,V,...&gt;

随着 C++0x 的出现以及拥有模板 typedef 和可变参数模板参数的能力,这似乎应该是可能的。

对我来说显而易见的解决方案是:

template <typename T>
using Action<T> = void (*)(T);

但是,这不适用于仿函数或 C++0x lambda,除此之外,编译时不会出现错误“expected unqualified-id before 'using'

我的下一个尝试可能是使用 boost::function:

template <typename T>
using Action<T> = boost::function<void (T)>;

出于同样的原因,这也无法编译。

我唯一的其他想法是 STL 样式模板参数:

template <typename T, typename Action>
void foo(T value, Action f) {
    f(value);
}

但这并没有提供强类型的解决方案,并且只在模板化函数内部相关。

现在,我将第一个承认我不是我更愿意认为自己是的 C++ 专家,所以很可能有一个我没有看到的明显解决方案。

是否可以在 C++ 中使用 C# 风格的泛型函数类型?

【问题讨论】:

  • 不,这是不可能的。不完全的。它们是不同的语言。问题是最接近的近似值是什么,根据您的需要。您是否需要类型擦除,因此具有相同签名的每个仿函数都显示为相同类型?如果是这样,您将不得不跳过一些障碍,并失去一些效率。而且通常不值得这样做,因为由于模板和泛型之间的差异,它通常不是必要的。经常,但并非总是如此。你到底需要什么?除了一味地试图在 C++ 中模仿 C#

标签: c# c++ templates lambda c++11


【解决方案1】:

我觉得语法应该是这样的:

template <typename T>
using Action = void (*)(T);

不过,我也无法编译它 (g++ v4.3.2)。

一般 STL 风格的函数模板不是严格意义上的强类型,但它是类型安全的,因为编译器将确保模板仅针对满足函数所有要求的类型进行实例化。具体来说,如果Action 不能使用T 类型的一个参数调用,这将是一个编译器错误。这是一种非常灵活的方法,因为Action 是否被实例化为实现operator() 的函数或某个类并不重要。

对于缺少模板化的 typedef,旧的非 C++0x 解决方法是使用带有嵌套 typedef 的模板化结构:

template <typename T>
struct Action {
   typedef boost::function<void (T)> type;
};

template <typename T>
void foo(T value, typename Action<T>::type f) {
    f(value);
}

【讨论】:

    【解决方案2】:

    Gcc 还不支持模板别名(参见here),我不确定是否考虑了可变模板别名。我不认为其他编译器已经支持此功能。

    我将只使用 std::function 或 std::function 而不是 Action 或 Func。

    当然,您可以从 std::function 定义可变参数模板类 Action 或 Func,但我看不出有什么好处。

    【讨论】:

      【解决方案3】:

      我不认为泛型函数类型是直观的 C​​++,因为 C++ 模板的工作方式与泛型不同。

      C++ 的方式是使用函数对象——任何你可以放在() 之后的东西,这对编译器来说是有意义的。这可以是函数指针、带有operator() 的类等等。这是可行的,因为 C++ 模板就像花哨的宏,只要代码对替换的类型有意义,就可以了。

      C# 泛型不是这样工作的——它们更具限制性,可能是为了改进错误消息(因为 C++ 模板出错在输出中是出了名的冗长)。我对 C# 泛型了解不多,但我认为它们依赖于更像回调的东西,因此函数泛型的用处。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-10-31
        • 1970-01-01
        • 1970-01-01
        • 2011-06-24
        • 1970-01-01
        • 1970-01-01
        • 2018-07-15
        相关资源
        最近更新 更多