【问题标题】:C++ generic template method name from template parameter来自模板参数的 C++ 通用模板方法名称
【发布时间】:2015-10-13 09:38:36
【问题描述】:

我从 C++11 中的可变参数模板开始,我想知道是否可以创建一个从模板参数获取名称的结构/类方法

类似:

MySmartTemplate<"foo", int, "bar", double> MyStruct;

// which should result in:
struct MyStruct
{
   void foo(int val){...}
   void bar(double val){...}
};

模板参数可能成对出现 +

谢谢

【问题讨论】:

  • 没有。但是可以使用预处理器宏。
  • 简短而唯一的答案是不,这是不可能的,无论如何都不能使用模板。

标签: c++ templates c++11


【解决方案1】:

模板根本不可能做到这一点。 c++ 中的模板由一个或多个模板参数的列表参数化。它们中的每一个都可能是:

  • 非类型模板参数;
  • 类型模板参数;
  • 模板模板参数。

现在,为了能够(理论上)构造void foo(int val){...} 之类的东西,您需要将“foo”的名称及其参数类型传递到我们想象的模板中。虽然传递val 的类型不是问题,但传递“foo”的名字是不可能的。您可以使用的唯一非类型模板参数是:

  • std::nullptr_t;
  • 整体式;
  • 左值引用类型(对象或函数);
  • 指针类型(指向对象或函数);
  • 指向成员类型的指针(指向成员对象或成员函数);
  • 枚举类型。

您还应该注意,引用和指针类型的非类型模板参数有一些例外,即它们不能引用或作为字符串文字的地址(相关:this question)。考虑到上述情况,没有办法将字符串文字传递给模板,因此无法使用模板实现您想要的。

附带说明,虽然可变参数模板是该语言的一个很好的补充,但它们有一些限制,即您只能执行参数包的扩展,但不能处理包中的单个参数。

因此,总而言之,不,模板无法实现您想要的。

【讨论】:

  • ...好吧,这不太好。如果函数“name”会被一个索引替换,比如元组 get(i)?
  • @xy,你可以将函数指针存储在地图中,并通过作为模板参数传递的索引将它们从那里取出,但我不明白你为什么需要使用模板完全为了那个。
  • 除了添加 /removin 一些模板参数 - 它是关于排序的。假设模板参数的顺序很重要,因此参数包中第一个出现的参数与其他参数包中的参数不同......
【解决方案2】:

很遗憾,没有。模板机制只允许您享受类型通用性的乐趣,即创建可以与多种类型一起使用的函数/对象,或者对不同的输入类型有略微不同的实现,或者使返回类型取决于模板参数等。一般来说,模板元编程引入了所谓的静态多态性。这是compiler 阶段的功能(查看compilation stages),这意味着它在所有名称都固定后完成(函数foo() 将始终被称为foo,即使编译器决定将它与int 参数一起使用)。

您想要实现的是进入proprocessor 阶段,在该阶段可以使用preprocessor directives 修改源代码。这是您可以使用宏的时刻。对于您的示例,您可以使用以下内容:

#include <iostream>

using namespace std;

#define MySmartTemplate(StructName, Func1Name, Func1ArgType, Func2Name, Func2ArgType) \
struct StructName \
{ \
    void Func1Name(Func1ArgType val) { cout << "func1" << endl; } \
    void Func2Name(Func2ArgType val) { cout << "func2" << endl; } \
};

MySmartTemplate(MyStruct, foo, int, bar, double);

int main()
{
    MyStruct myStruct;
    myStruct.foo(1);
    myStruct.bar(1);
}

Live demo


当然,您可以将宏与模板一起使用,这将为您提供更大的灵活性。

【讨论】:

  • “模板机制只允许您享受类型通用性的乐趣,即创建可以与多种类型一起使用的函数/对象”。因此,如果我将不同的 函数指针 作为模板参数传递,它会 - 有点 - 模拟我的想法......,我会看看,但感谢澄清......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多