模板函数作为模板参数
我只是对如何在 C++ 中以通用方式实现某些东西感到困惑。这有点复杂,所以让我一步步解释。
考虑这样的代码:
void a(int) {
// do something
}
void b(int) {
// something else
}
void function1() {
a(123);
a(456);
}
void function2() {
b(123);
b(456);
}
void test() {
function1();
function2();
}
很容易注意到 function1
和 function2
执行相同的操作,唯一不同的部分是内部函数。
因此,我想让 function
通用以避免代码冗余。我可以使用函数指针或模板来做到这一点。现在让我选择后者。 我的想法是,它更好,因为编译器肯定能够内联函数 - 我是对的吗?如果通过函数指针进行调用,编译器仍然可以内联这些调用吗?这是一个附带问题。
好吧,回到原点...带有模板的解决方案:
void a(int) {
// do something
}
void b(int) {
// something else
}
template<void (*param)(int) >
void function() {
param(123);
param(456);
}
void test() {
function<a>();
function<b>();
}
一切OK。但我遇到了一个问题:如果 a
和 b
本身就是泛型,我还能这样做吗?
template<typename T>
void a(T t) {
// do something
}
template<typename T>
void b(T t) {
// something else
}
template< ...param... > // ???
void function() {
param<SomeType>(someobj);
param<AnotherType>(someotherobj);
}
void test() {
function<a>();
function<b>();
}
我知道模板参数可以是以下之一:
- 类型、
- 模板类型、
- 类型的值。
这些似乎都不能涵盖我的情况。因此,我的主要问题是:如何解决这个问题,即在最后一个示例中定义 function()
?
(是的,函数指针似乎是一种解决方法这个确切的情况 - 前提是它们也可以内联 - 但我正在寻找此类问题的通用解决方案)。
I've just got confused how to implement something in a generic way in C++. It's a bit convoluted, so let me explain step by step.
Consider such code:
void a(int) {
// do something
}
void b(int) {
// something else
}
void function1() {
a(123);
a(456);
}
void function2() {
b(123);
b(456);
}
void test() {
function1();
function2();
}
It's easily noticable that function1
and function2
do the same, with the only different part being the internal function.
Therefore, I want to make function
generic to avoid code redundancy. I can do it using function pointers or templates. Let me choose the latter for now. My thinking is that it's better since the compiler will surely be able to inline the functions - am I correct? Can compilers still inline the calls if they are made via function pointers? This is a side-question.
OK, back to the original point... A solution with templates:
void a(int) {
// do something
}
void b(int) {
// something else
}
template<void (*param)(int) >
void function() {
param(123);
param(456);
}
void test() {
function<a>();
function<b>();
}
All OK. But I'm running into a problem: Can I still do that if a
and b
are generics themselves?
template<typename T>
void a(T t) {
// do something
}
template<typename T>
void b(T t) {
// something else
}
template< ...param... > // ???
void function() {
param<SomeType>(someobj);
param<AnotherType>(someotherobj);
}
void test() {
function<a>();
function<b>();
}
I know that a template parameter can be one of:
- a type,
- a template type,
- a value of a type.
None of those seems to cover my situation. My main question is hence: How do I solve that, i.e. define function()
in the last example?
(Yes, function pointers seem to be a workaround in this exact case - provided they can also be inlined - but I'm looking for a general solution for this class of problems).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
为了用模板解决这个问题,你必须使用模板模板参数。
不幸的是,您不能将模板模板函数作为类型传递,因为它必须首先实例化。但有一个针对虚拟结构的解决方法。这是一个例子:
In order to solve this problem with templates, you have to use a template template parameter.
Unfortunately, you cannot pass template template function as a type, because it has to be instantiated first. But there is a workaround with dummy structures. Here is an example:
使用 C++14 中的泛型 lambda,您可以这样做:
它们可以,但它确实更复杂,并且它们可能比函子或模板更容易失败。
With generic lambda from C++14 you might do:
They can, but it is indeed more complicated, and they may fail more often than with functor or template.
这是一个方法。它可能不是最好的,但它有效:它们是否会被内联取决于编译器,但如果它们不是,我会感到相当惊讶。编辑:好的,今天有点走神,错过了参数不同类型的部分。我的不好。
使用模板可能有一种棘手的方法,但这是我能想到的最简单的方法:
我知道,我知道,“宏是邪恶的”,等等等等。有用。如果
function
需要比您的示例更复杂,您可能会遇到问题,但它比我能想到的任何东西都容易得多。Here's a way. It may not be the best, but it works:Whether or not they'll be inlined depends on the compiler, but I would be rather surprised if they weren't.EDIT: Okay, I'm a little off today and missed the part where the parameters are of different types. My bad.
There may be a tricky way to do this with templates, but this is the easiest way I could think of:
I know, I know, "macros are evil," blah blah blah. It works. If
function
needs to be more complicated than your example you may run into problems, but it is much easier than anything I've been able to come up with.