C++ 如何构造可以调用和返回两种不同类型的模板

C++ 如何构造可以调用和返回两种不同类型的模板,c++,templates,C++,Templates,我正在编写一些代码,其中我有两个类,每个类都有一个方法,该方法返回带有特定值的类。现在这两个类有不同的名称,返回具有特定值的类的方法有不同的名称,但是值是相同的 范例 class_a a = class_a::get_value_a() class_b b = class_b::get_value_b() a.value() == b.value() is true class_generic g_a = class_generic::get_value<cla

我正在编写一些代码,其中我有两个类,每个类都有一个方法,该方法返回带有特定值的类。现在这两个类有不同的名称,返回具有特定值的类的方法有不同的名称,但是值是相同的

范例

   class_a a = class_a::get_value_a()
   class_b b = class_b::get_value_b()

   a.value() == b.value() is true
   class_generic g_a = class_generic::get_value<class_a>();
   class_generic g_b = class_generic::get_value<class_b>();

   g_a.value() == g_b.value() is true
现在我要做的是使用模板获得这个值的一般方法

范例

   class_a a = class_a::get_value_a()
   class_b b = class_b::get_value_b()

   a.value() == b.value() is true
   class_generic g_a = class_generic::get_value<class_a>();
   class_generic g_b = class_generic::get_value<class_b>();

   g_a.value() == g_b.value() is true
但在制作模板时,我尝试了以下步骤

template <typename T> T class_generic::get_value()
{
  if (typeid(T).hash_code() == typeid(class_a).hash_code())
  {
    return class_a::get_value_a()
  }
  if (typeid(T).hash_code() == typeid(class_b).hash_code())
  {
    return class_b::get_value_b();
  }
}
但这不会编译,而且在我看来,它试图解析两种返回类型并转换一种

那么我如何正确地做到这一点呢

关于

您可以申请。e、 g

或者从C++17开始应用,其条件在编译时计算,这样可以避免代码段遇到的问题。e、 g

template <typename T>
T class_generic::get_value()
{
  if constexpr (std::is_same_v<T, class_a>)
  {
    return class_a::get_value_a();
  } 
  else if constexpr (std::is_same_v<T, class_b>)
  {
    return class_b::get_value_b();
  } 
  else 
  {
    // return something else..
  }
}
你可以申请。e、 g

或者从C++17开始应用,其条件在编译时计算,这样可以避免代码段遇到的问题。e、 g

template <typename T>
T class_generic::get_value()
{
  if constexpr (std::is_same_v<T, class_a>)
  {
    return class_a::get_value_a();
  } 
  else if constexpr (std::is_same_v<T, class_b>)
  {
    return class_b::get_value_b();
  } 
  else 
  {
    // return something else..
  }
}

在当前的标准中,这可以按如下方式进行

struct class_generic {
    template<typename T> T get_value() {
        if constexpr(std::is_same_v<T, class_a>) {
            return class_a::get_value_a();
        }
        else return class_b::get_value_b();
    }
};

请注意,如果无法同时编译这两个备选方案,即代码的一部分仅针对一个模板参数值进行编译,而另一部分针对另一个模板参数值进行编译,则它们应该是同一if-constexpr/else运算符的不同分支。

在当前标准中,这可以按照

struct class_generic {
    template<typename T> T get_value() {
        if constexpr(std::is_same_v<T, class_a>) {
            return class_a::get_value_a();
        }
        else return class_b::get_value_b();
    }
};

请注意,如果无法同时编译这两个备选方案,即一部分代码仅编译一个模板参数值,另一部分代码编译另一个模板参数值,则它们应该是同一if-constexpr/else运算符的不同分支。

除了已经给出的正确解决方案,您应该注意到,typeid是一个运行时操作符,用于在运行时检查多态类型,无论模板是否是编译时问题。因此,在代码中的模板求值期间不会对typeid求值。

除了已经给出的正确解决方案之外,您应该注意,typeid是一个运行时操作符,用于在运行时检查多态类型,无论模板是否是编译时问题。因此,在代码中的模板求值期间,不会对typeid求值。

在问题中,两个理论函数都返回类\u generic。如果函数返回相同的对象类型(比如存储在列表中)很重要,那么这将不起作用。我认为预期用途需要一些澄清。@T将mrt指定为返回类型,因此我支持将class_a或class_b指定为返回类型。两者都可以转换为class_generic?我发布了一个非常简化的代码版本,只是为了说明我需要解决的问题。但是宋元耀是对的,我需要不同的类作为返回类型。@宋元耀我是朝这个方向工作的,似乎我犯了一个错误,谢谢你的简单示例。我不在C++17上工作,所以我不能使用这个例子。在这个问题中,两个理论函数都返回类_generic。如果函数返回相同的对象类型(比如存储在列表中)很重要,那么这将不起作用。我认为预期用途需要一些澄清。@T将mrt指定为返回类型,因此我支持将class_a或class_b指定为返回类型。两者都可以转换为class_generic?我发布了一个非常简化的代码版本,只是为了说明我需要解决的问题。但是宋元耀是对的,我需要不同的类作为返回类型。@宋元耀我是朝这个方向工作的,似乎我犯了一个错误,谢谢你的简单示例。我不在C++17上工作,因此无法使用该示例。