模板函数返回不同的类型
Template function to return different types
是否有可能在运行时确定不同类型的方法返回值?
我正在写一些东西,将编码和解码使用不同的密码。每个密码都有一个不同类型的密钥,在某些阶段,我需要允许密码获取这个密钥。
为了避免编写三个(目前有三个密码)单独的方法来返回不同类型的密钥,并且一次只使用一个密码,我试图做以下操作:
in parser.h
:
template <typename T>
T get_key(void) const;
in parser.cpp
:
/**
* The key to be used for encoding or decoding.
*
* @return The key to be used.
*/
template <typename T>
T cmdline_parser::get_key(void) const
{
if (vm.count("xor") > 0)// if xor cipher in use
return vm["xor"].as<long>();// returns a key of type long
else if (vm.count("caesar") > 0)// if caesar cipher in use
return vm["caesar"].as<int>();// returns a key of type int
else// vignere cipher in use
return vm["vignere"].as<std::string>();// returns a key of type std::string
}
我是如何使用它的:
Crypt<VignereCipher, std::string, Group, Pack> c(parser.get_key());
使用clang++
编译得到:
main.cpp:42:61: error: no matching member function for call to 'get_key'
Crypt<VignereCipher, std::string, Group, Pack> c(parser.get_key());
~~~~~~~^~~~~~~
和
./cmdline_parser.h:40:7: note: candidate template ignored: couldn't infer template argument 'T'
T get_key(void) const;
^
您可以使用3种方法,所有这些方法都在评论中提到过。以下是在它们之间进行选择的更多细节和权衡:
-
工厂方法。正如@KerrekSB在评论中提到的,您必须定义每个键类型的抽象基类和子类。工厂函数的返回类型是指向
AbstractKey
的指针(最好是处理资源管理的智能指针)。然而,工厂的实现是基于您正在解析的运行时值的if-else
阶梯、switch
语句或花哨的表查找。这是因为协变返回类型。有关工作示例,请参见本网站的设计模式。主要的缺点是你必须编写大量的样板(例如,向工厂注册新类型等),内置类型被排除在外,并且你返回的对象没有值语义。 -
Boost.Variant 。@AnatolyS在评论中提到了这一点。这种方法将有限数量的不相关类型包装在联合中,并允许您一次只使用其中一种类型,而不会产生动态分配开销。有关如何使用它,请参阅Boost文档。它的主要缺点是它的可扩展性不强,而且要动态选择您想要的键类型需要相当多的技巧。
-
Boost.Any 。这将两种解决方案一般化,将任意数量的不相关类型包装在一个holder对象中。其主要优点是具有值语义,而无需手动内存管理(尽管这是在后台完成的)。唯一实际的缺点是它需要Boost,这在一些限制性的公司设置中是不可能的。
- 如何在模板参数中分离函数类型返回类型和参数
- 为什么要为指针返回类型返回一系列字符?
- 有没有办法根据运行时值的类型返回 constexpr 对象
- 从弱指针返回类型返回共享指针
- 无法为unique_ptr返回类型返回 nullptr
- 为什么双重类型返回无穷大
- std::is_arithmetic 为通用 lambda 中的 int 类型返回 false:未定义的行为?
- C 策略设计具有可变类型返回值
- 根据类型返回一个值
- 在C++中,将double转换为long的类型返回了不正确的值
- 作为宏参数的安装类型返回错误:字符串常量之前的预期非限定 id
- 具有引用类型返回的函数
- C++ 如何使模板<T>f() 为整数 T 返回 -1,为指针类型返回 nullptr
- C++模板:按类型返回值
- 以Integer返回类型返回浮点值
- 使用 C++14 的自动功能类型返回扣除代替 std::common_type 是否始终安全?
- 为什么允许新运算符向每个指针类型返回*void
- 适当的函数返回类型返回日期时间
- c++中布尔类型返回函数的默认返回值
- 在c#中使用非托管c++代码对所有double类型返回0