Я знаю, что для функций и методов класса не поддерживается частная специализированная специализация, поэтому мой вопрос: Каковы общие решения или шаблоны для решения этой проблемы? Ниже Derived
происходит от Base
, и оба эти класса имеют виртуальные методы greet()
и speak()
. Foo
имеет номер std::array<unique_ptr<T>, N>
и используется в do_something()
. Foo
имеет два параметра шаблона: T
(тип класса) и N
(количество элементов std::array
) Если N
= 2, существует высоко оптимизированная версия do_something()
. Предположим теперь, что параметр Foo
10 не всегда является базовым классом Base
. В идеале, я хотел бы написать следующий код, но это незаконно:Частичная функция/метод шаблона обходные методы
//ILLEGAL
template<typename T>
void Foo<T,2>::do_something()
{
arr_[0]->greet();
}
Ниже приведен полный код и мой текущий (некрасиво) решение. Я должен специализироваться на do_something()
дважды, один раз за Base
и один раз за Derived
. Это становится уродливым, если существует несколько методов, таких как do_something()
, которые можно оптимизировать по специальному случаю N
= 2, и если существует много подклассов Base
.
#include <iostream>
#include <memory>
class Base
{
public:
virtual void speak()
{
std::cout << "base is speaking" << std::endl;
}
virtual void greet()
{
std::cout << "base is greeting" << std::endl;
}
};
class Derived : public Base
{
public:
void speak()
{
std::cout << "derived is speaking" << std::endl;
}
void greet()
{
std::cout << "derived is greeting" << std::endl;
}
};
template<typename T, int N>
class Foo
{
public:
Foo(std::array<std::unique_ptr<T>, N>&& arr) :
arr_(std::move(arr))
{
}
void do_something();
std::array<std::unique_ptr<T>, N> arr_;
};
template<typename T, int N>
void Foo<T,N>::do_something()
{
arr_[0]->speak();
}
//Want to avoid "copy-and_paste" of do_something() below
template<>
void Foo<Base,2>::do_something()
{
arr_[0]->greet();
}
template<>
void Foo<Derived,2>::do_something()
{
arr_[0]->greet();
}
int main()
{
constexpr int N = 2;
std::array<std::unique_ptr<Derived>, N> arr =
{
std::unique_ptr<Derived>(new Derived),
std::unique_ptr<Derived>(new Derived)
};
Foo<Derived, N> foo(std::move(arr));
foo.do_something();
return 0;
}
Мне интересно узнать больше. Не могли бы вы связать меня с тем, что вы подразумеваете под «использованием существующих инструментов на C++». Благодарю. –
@anon: 'std :: integ_constant', например, может использоваться для отправки тегов и соответствует потребностям данной конкретной проблемы. –