C++0x 中的 C# 风格 Action、Func

发布于 2024-08-29 14:50:23 字数 815 浏览 3 评论 0原文

C# 具有通用函数类型,例如 ActionFunc

随着 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# has generic function types such as Action<T> or Func<T,U,V,...>

With the advent of C++0x and the ability to have template typedef's and variadic template parameters, it seems this should be possible.

The obvious solution to me would be this:

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

however, this does not accommodate for functors or C++0x lambdas, and beyond that, does not compile with the error "expected unqualified-id before 'using'"

My next attempt was to perhaps use boost::function:

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

This doesn't compile either, for the same reason.

My only other idea would be STL style template arguments:

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

But this doesn't provide a strongly typed solution, and is only relevant inside the templated function.

Now, I will be the first to admit that I am not the C++ wiz I prefer to think I am, so it's very possible there is an obvious solution I'm not seeing.

Is it possible to have C# style generic function types in C++?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

九公里浅绿 2024-09-05 14:50:24

我认为语法应该是这样的:

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);
}

I think the syntax should be like this:

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

I couldn't get that to compile either, though (g++ v4.3.2).

The general STL style function template is not strongly typed in the strictest sense, but it is type safe in the sense that the compiler will ensure that the template is only instantiated for types that fulfill all the requirements of the function. Specifically it will be a compiler error if the Action is not callable with one parameter of type T. This a very flexible approach since it doesn't matter if Action is instantiated to be a function or some class that implements operator().

The old non-C++0x workaround for the missing templated typedef would be to use a templated struct with a nested 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);
}
云淡月浅 2024-09-05 14:50:24

Gcc 尚不支持模板别名(请参阅此处),而且我不支持确定是否考虑可变参数模板别名。我认为其他编译器尚未支持此功能。

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

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

Gcc doesn't support yet template aliases (see here), and I'm not sure if variadic template alias are considered. I don't think other compilers support already this feature.

I will just use std::function or std::function instead of Action or Func.

Of course you can define variadic template classes Action or Func from std::function but I don't see the benefit.

嘿嘿嘿 2024-09-05 14:50:24

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

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

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

I don't think a generic function type is intuitive C++, because C++ templates work differently to generics.

The C++ way is to use function objects - anything which you can put () after and it makes sense to the compiler. This can be a function pointer, a class with operator(), and so on. This works because C++ templates are like fancy macros, and as long as the code makes sense with the types substituted you're OK.

C# generics don't work like that - they're more restrictive, probably in an effort to improve error messages (since getting C++ templates wrong is famously verbose in the output). I don't know too much about C# generics, but I think they rely on something which is more like callbacks, hence the usefulness of the function generics.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文