У меня есть код с большим количеством шаблонов, в котором классы, которые должны использоваться в качестве параметров шаблона для пользовательского кода, имеют разные подписи конструктора. Моя проблема в том, что я не нашел хорошего способа вызвать конструкторы шаблонных классов в своем пользовательском коде. Мимимальный рабочий пример может выглядеть так:
#include <string>
#include <iostream>
#include <memory>
class ShortConstructorInLibrary {
std::string myName;
static const int tag = 1;
public:
ShortConstructorInLibrary(std::string name) :
myName(name) {
}
};
class LongConstructorInLibrary {
private:
int a;
double b;
public:
static const int tag = 2;
LongConstructorInLibrary(int arg1, double arg2) :
a(arg1), b(arg2) {
}
};
//above is library code
template<typename T>
class MyClass {
std::shared_ptr<T> member_p;
//i want to call right constructor for both cases:
public:
MyClass() {
//how do i call the different constructors properly?!
member_p = std::shared_ptr<T>(new T("test"));
}
};
int main() {
MyClass<ShortConstructorInLibrary> obj; //works
//MyClass<LongConstructorInLibrary> obj2; // wrong constructor signature
}
Здесь у меня есть два класса в библиотеке, один с длинной и несвязанной сигнатурой конструктора, другой с короткой. Я хочу иметь возможность использовать их оба в качестве параметров шаблона. В моем пользовательском классе я каким-то образом должен определить, какие аргументы передавать конструкторам в зависимости от переданного типа.
Я не могу использовать простой if(), потому что компилятор проверит обе подписи, и одна из них будет неправильной. Я не могу использовать С++ 17 для «if constexpr () {}».
Я могу передать параметр шаблона «ShortConstructorInLibrary» в свой класс и вызвать его конструктор в полном порядке, но когда я использую другой класс, он, конечно, не сработает из-за неправильной подписи конструктора. До сих пор я использовал уродливый трюк, реализовав два вспомогательных метода, в которых я передаю указатель, а затем позволяю двум методам реализовывать вызовы конструктора, но мне это кажется уродливым. Я также возился с std::enable_if‹>, но далеко не продвинулся. @Mohit предложил использовать частичную специализацию шаблона, но в реальном коде класс Short ConstructorInLibrary сам по себе шаблонен с парой ... аргументов шаблона шаблона. Чтобы дать вам представление:
‘class CFEM_LOP<Dune::PDELab::QkLocalFiniteElementMap<Dune::GridView<Dune::DefaultLeafGridViewTraits<const Dune::YaspGrid<2> > >, double, double, 1ul>, EngwHillenKnapp2014<MedicalDataManager<double, Dune::YaspGrid<2> >, Dune::YaspGrid<2> >, CFEM_L2OP<Dune::PDELab::QkLocalFiniteElementMap<Dune::GridView<Dune::DefaultLeafGridViewTraits<const Dune::YaspGrid<2> > >, double, double, 1ul> >, Dune::YaspGrid<2> >’
Я понял, что попытка специализировать мой пользовательский код будет адским беспорядком.
Как правильно реализовать вызовы конструктора с возможными разными сигнатурами?
любые подсказки будут оценены!
(убунту 16.04, gcc)
if constexpr
иstd::is_same
- person Mohit   schedule 05.07.2018