c++模板:我可以调用基于输入类型名称的函数吗?

C++ templates: can I call a function whose name is based on the input type name?

本文关键字:类型 函数 输入 我可以 模板 调用 于输入 c++      更新时间:2023-10-16

我有一个代码库,其中有许多返回单例的枚举相关函数。它们的名字是公式化的:

enum Foo {...};
const MySingleton* Foo_Singleton();
enum Bar {...};
const MySingleton* Bar_Singleton();
...

是否有可能编写一个c++模板,将选择正确的getter函数名,而不显式列出所有选项?

template <typename EnumT>
inline const MySingleton* Get() {
  return EnumT ## _Singleton();
}

我知道我在这里使用了一个无意义的预处理器指令,但我希望它能传达我的目的。我知道我可以为每个枚举编写重载,但是枚举很多,维护起来很麻烦,所以我宁愿避免这种解决方案。

最简单的方法是更改您的命名策略:

enum Foo {...};
const MySingleton* Get(Foo); // instead of const MySingleton* Foo_Singleton();
enum Bar {...};
const MySingleton* Get(Bar); // instead of const MySingleton* Bar_Singleton();

所涉及的机制称为标签调度。现在您可以通过简单的

获得适当的单例实例:
Get(Foo{});

其中一种可能性:

// template specification (to be specialized)
template <typename EnumT>
const MySingleton* Get();
#define JOIN_IMPL(a, b) a ## b
#define JOIN(a, b) JOIN_IMPL(a, b)
// template specialization for particular enum
#define DEFINE_GET_SINGLETON(EnumT)       
template<>                                
inline const MySingleton* Get<EnumT>() {  
  return JOIN(EnumT, _Singleton)();       
}
DEFINE_GET_SINGLETON(Foo)
DEFINE_GET_SINGLETON(Bar)

通过使用宏,您可以节省一些输入(以调试为代价-大多数调试器不能逐步执行宏)。

我怀疑将宏和模板混合在一起的解决方案在这里是可能的。

一个可以工作的基于模板的解决方案,但是需要为每个类型声明一个包装器函数。

首先定义这些函数:

const MySingleton* GetSingleton( Foo* var ) { return Foo_Singleton(); }
const MySingleton* GetSingleton( Bar* var ) { return Bar_Singleton(); }

然后输入:

template <typename EnumT>
inline const MySingleton* Get() {
  EnumT e;
  return GetSingleton( &e );
}

然后编译器将根据EnumT选取相应的GetSingleton

注意,您可以使用宏来声明函数,但我不确定它是否非常有用:

#define DECLARE_WRAPPER(TYPE) const MySingleton* GetSingleton( TYPE* var ) { return TYPE##_Singleton(); }
DECLARE_WRAPPER( Foo )
DECLARE_WRAPPER( Bar )