Как создать шаблон, который может вызывать и возвращать два разных типа - PullRequest
0 голосов
/ 04 октября 2018

Я работаю над кодом, в котором у меня есть два класса, каждый с методом, который возвращает указанный класс с определенным значением.Теперь эти два класса имеют разные имена, а методы, которые возвращают указанный класс с определенным значением, имеют разные имена, однако значение одно и то же.

пример

   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();
  }
}

Но это не скомпилируется, и мне кажется, что он пытается разрешить оба возвращаемых типа и конвертирует один.

Так как мне сделать это правильно?

regards

Ответы [ 3 ]

0 голосов
/ 04 октября 2018

В текущем стандарте это можно сделать как

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.

0 голосов
/ 04 октября 2018

Помимо уже приведенных правильных решений, вы должны заметить, что typeid () является оператором времени выполнения для проверки полиморфного типа во время выполнения, независимо от того, являются ли шаблоны проблемой времени компиляции.Таким образом, typeid не будет оцениваться во время оценки шаблона в вашем коде.

0 голосов
/ 04 октября 2018

Вы можете применить шаблон специализации .Например,

// primary template
template <typename T> 
T class_generic::get_value();

// explicit specialization for T = class_a
template <> 
class_a class_generic::get_value<class_a>()
{
  return class_a::get_value_a();
}

// explicit specialization for T = class_b
template <> 
class_b class_generic::get_value<class_b>()
{
  return class_b::get_value_b();
}

Или применить Constexpr Если (начиная с C ++ 17), чье условие оценивается во время компиляции, а затем может избежать проблемы, с которой столкнулся ваш фрагмент кода.например,

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..
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...