C++ 如何按标签调度到不同的模板函数

C++ How to dispatch to different template function by tag

本文关键字:函数 何按 标签 调度 C++      更新时间:2023-10-16

有很多模板函数叫做f1,f2,f3...

如何将运行时已知的 int 调度到不同的模板函数?

当然,我可以使用switch来做到这一点,但是每次添加更多模板函数或删除一些模板函数时,我都必须一次又一次地修改开关。我怎样才能以更优雅的方式做到这一点?

模板不是实际的函数,因此我无法制作 std::map 函数指针。

template<typename T> std::optional<T> f1(){...}
template<typename T> std::optional<T> f2(){...}
template<typename T> std::optional<T> f3(){...}
template<typename T> std::optional<T> f4(){...}
template<typename T> auto dispatch(int tag){
switch(i){
case 1: return f1<T>();
case 2: return f2<T>();
case 3: return f3<T>();
case 4: return f4<T>();
}// I have to modify these if add or delete some template functions
}

这是命令模式的解释,我想这是你要找的。

没有模板化函数,所以我重写了它。它没有做它的目的(转换数字(,但您可以选择要调用的函数及其模板化。

#include <iostream>
#include <string>
#include <bitset>
#include <sstream>
#include <map>
#include <cctype>
template <typename T>
class converter
{
public:
virtual std::string convert(T) = 0;
virtual ~converter() {}
};
template <typename T>
class hex_converter : public converter<T>
{
public:
std::string convert(T i)
{
return "H: " + i;
}
};
template <typename T>
class oct_converter : public converter<T>
{
public:
std::string convert(T i)
{
return  "O: " + i;
}
};
template <typename T>
class bin_converter : public converter<T>
{
public:
std::string convert(T i)
{
return "B: " + i;
}
};

class dictionary
{
std::map<char, converter<std::string>*> dict;
public:
dictionary()
{
dict.insert( std::make_pair( 'B', new bin_converter<std::string> ) );
dict.insert( std::make_pair( 'O', new oct_converter<std::string> ) );
dict.insert( std::make_pair( 'H', new hex_converter<std::string> ) );
}
converter<std::string>* lookup(char x)
{
std::map<char, converter<std::string>*>::const_iterator iter;
iter = dict.find( toupper(x) );
if( iter != dict.end() )
return iter->second;
else
return NULL;
}
~dictionary()
{
while( dict.begin() != dict.end() )
{
delete dict.begin()->second;
dict.erase( dict.begin() );
}
}
};
int main()
{
using namespace std;
char ch = 'h';
string output = "";
dictionary dict;
converter<std::string>* con = dict.lookup( ch );
if( con != NULL )
output = con->convert( "Test" );
else
output = "Invalid";
cout << "Result: " << output;
}