所以在C ++中我们可以将函数作为模板参数传递,如下所示:
template <typename func>
int tester(func f)
{
return f(10);
}
所以我有一个使用函数的模板类,我一直在使用它,每次我都会将函数和变量传递给它。
template <typename type_t>
class TCl
{
...
template <typename func>
int Test(func f, type_t Var>
{
// Blah blah blah
}
};
但我想将该函数作为类模板参数之一,以使其更易于使用。 所以我首先尝试了这个:
template <typename func>
template <typename type_t, func f>
class TCl
{
...
};
但是当我编译它时,我得到:
编译器错误C3857:不允许使用多个类型参数列表
因为上帝禁止我的代码应该在我第一次尝试时编译。
现在我的问题是虽然我知道函数的参数类型(在这种情况下是size_t,size_t),但返回类型可以是任何东西,只要有适当的type_t比较运算符。
经过几个小时的在线阅读后,我找到了一个有效的解决方案。
template <typename type_t, typename ret_t, ret_t f(size_t, size_t)>
class TCl
{
...
};
虽然它有效但它破坏了代码的审美。我更喜欢在原始示例中指定func类型的东西,并且不必担心指定返回类型。
那么有人有任何建议吗?
此外,没有提升。
编辑: 解决!
谢谢你们。我使用了Jarod42的解决方案。
@Drax&amp;轨道中的轻盈竞赛:
我曾考虑过将这个类型放在手边,但它会给程序员带来负担来定义函数指针以便使用它,这似乎不必要地残忍:)
然而,Jarod42解决了使用宏和decltype运算符,我已经完全忘记了。
您的示例Jarod42存在轻微问题。
#define TCl_T(type_t, function) Tcl<type_t, decltype(function), function>
生成错误: 错误C1001:编译器中发生内部错误。
这解决了它。
#define TCl_T(type_t, function) Tcl<type_t, decltype(&function), function>
显然我们必须指明它是一个指针。
再次感谢帮助人员!
答案 0 :(得分:2)
使用:
template <typename type_t, typename ret_t, ret_t f(size_t, size_t)>
class TCl;
您可以使用宏:
#define TCl_T(type_t, function) Tcl<type_t, decltype(function(0, 0)), function>
然后使用它:
// bool my_func(size_t, size_t);
TCl_T(int, my_func) tcl; // tcl is a Tcl<int, bool, my_func>
如果您将TCl更改为:
template <typename type_t, typename prototype_t, prototype_t f>
class TCl;
您可以使用宏:
#define TCl_T(type_t, function) Tcl<type_t, decltype(function), function>
答案 1 :(得分:1)
只需将模板参数放在同一行:
template <typename type_t, typename func, func f>
class TCl
{
...
};
答案 2 :(得分:1)
我非常喜欢在原始示例中指定func类型的内容,而不必担心指定返回类型。
好的,那就这么简单! :-)我不明白你为什么从传递整个函数类型作为模板参数,将其拆分为返回类型和参数类型。并且,在这样做时,您介绍了您所陈述的问题。但是你没有解释为什么你做了这个改变。
为什么不简单:
template <typename type_t, typename func_t, func_t f>
class TCl
{
// ...
};
这是你自己的方法的逻辑演变,不是吗?
这是一个有效的例子:
#include <iostream>
template <typename type_t, typename func_t, func_t f>
struct T
{
T() { f(); }
type_t a; /**< Irrelevant here, but gives your `type_t` something to do */
};
void foo() { std::cout << "A\n"; }
int bar() { std::cout << "B\n"; return 0; }
int main()
{
T<int, void(*)(), &foo> t1;
T<int, int (*)(), &bar> t2;
}
// Output:
// A
// B
遗憾的是,你无法在 template-argument-list 中使用更多的演绎。为了缩短调用次数,Jarod42对宏有一个有趣的想法,尽管我不确定它是否会改善美感。
我想知道这是否意味着你的断言:
使该函数成为类模板参数之一,以便于使用
是假的。