C++ 返回不同类型的模板函数

C++ 返回不同类型的模板函数,c++,function,templates,generics,C++,Function,Templates,Generics,有没有可能让一个方法返回不同类型的值,其类型在运行时确定 我写的东西将编码和解码使用不同的密码。每个密码都有一个不同类型的密钥,在某个阶段,我需要允许密码获取该密钥 为了避免编写三个(目前有三个密码)单独的方法来返回不同类型的密钥,并且一次只使用一个密码,我尝试执行以下操作: 在parser.h中: template <typename T> T get_key(void) const; 我如何使用它: Crypt c(parser.get_key()) 使用cla

有没有可能让一个方法返回不同类型的值,其类型在运行时确定

我写的东西将编码和解码使用不同的密码。每个密码都有一个不同类型的密钥,在某个阶段,我需要允许密码获取该密钥

为了避免编写三个(目前有三个密码)单独的方法来返回不同类型的密钥,并且一次只使用一个密码,我尝试执行以下操作:

parser.h
中:

    template <typename T>
    T get_key(void) const;
我如何使用它:

Crypt 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());
                                                 ~~~~~~~^~~~~~~

您可以使用3种方法,所有这些方法都在评论中提到。以下是一些更详细的信息和权衡,供您选择:

  • 工厂方法。正如@KerrekSB在评论中提到的,您必须定义一个抽象基类,并从中定义每个键类型的子类。工厂函数的返回类型是指向
    AbstractKey
    的指针(最好是处理资源管理的智能指针)。然而,工厂的实现是一个
    if-else
    ladder、
    switch
    语句或基于您正在解析的运行时值的高级pancy表查找。这之所以有效是因为。有关工作示例,请参见设计模式上的示例。主要缺点是您必须编写大量的模板(例如,向工厂注册新类型等),内置类型被排除在外,并且返回的对象没有值语义

  • 。@AnatolyS在评论中提到了这一点。这种方法将有限数量的不相关类型封装在一个联合中,并允许您在不需要动态分配开销的情况下同时只使用其中一种类型。有关如何使用它,请参阅Boost文档。主要缺点是它的可扩展性不强,动态选择所需的密钥类型需要相当长的时间

  • 。这将两种解决方案概括为在holder对象中包装任意数量的不相关类型。主要的优点是您具有值语义,并且没有手动内存管理(不过这是在幕后完成的)。唯一实际的缺点是它需要提升,这在一些限制性的公司环境中是不可能的


  • 您可以使用3种方法,所有这些方法都在评论中提到。以下是一些更详细的信息和权衡,供您选择:

  • 工厂方法。正如@KerrekSB在评论中提到的,您必须定义一个抽象基类,并从中定义每个键类型的子类。工厂函数的返回类型是指向
    AbstractKey
    的指针(最好是处理资源管理的智能指针)。然而,工厂的实现是一个
    if-else
    ladder、
    switch
    语句或基于您正在解析的运行时值的高级pancy表查找。这之所以有效是因为。有关工作示例,请参见设计模式上的示例。主要缺点是您必须编写大量的模板(例如,向工厂注册新类型等),内置类型被排除在外,并且返回的对象没有值语义

  • 。@AnatolyS在评论中提到了这一点。这种方法将有限数量的不相关类型封装在一个联合中,并允许您在不需要动态分配开销的情况下同时只使用其中一种类型。有关如何使用它,请参阅Boost文档。主要缺点是它的可扩展性不强,动态选择所需的密钥类型需要相当长的时间

  • 。这将两种解决方案概括为在holder对象中包装任意数量的不相关类型。主要的优点是您具有值语义,并且没有手动内存管理(不过这是在幕后完成的)。唯一实际的缺点是它需要提升,这在一些限制性的公司环境中是不可能的


  • 函数没有参数,编译器无法从任何地方推断类型。您听说过变量类型吗?变体将解决您的问题。听起来像多态类层次结构和工厂的经典案例。什么是
    vm
    set
    ?@AnatolyS我从未听说过变体类型@jrok vm是
    boost::program\u options::variables\u map
    函数没有参数,编译器无法从任何地方推断类型。您听说过variant type吗?变体将解决您的问题。听起来像多态类层次结构和工厂的经典案例。什么是
    vm
    set
    ?@AnatolyS我从未听说过变体类型@jrok虚拟机是
    boost::program\u options::variables\u map
    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;
      ^