Вызов различных сигнатур конструктора шаблонных типов

У меня под рукой шаблонный код, в котором классы, которые должны использоваться в качестве параметров шаблона для пользовательского кода, имеют разные сигнатуры конструктора. Моя проблема в том, что я не нашел хорошего способа вызова конструкторов шаблонных классов в моем пользовательском коде. Мимимальный рабочий пример может выглядеть так:

#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
}

Здесь у меня есть два класса в библиотеке, один с длинной и несвязанной сигнатурой конструктора, другой с короткой. Я хочу иметь возможность использовать их обоих в качестве параметров шаблона. В моем userClass я как-то должен определить, какие аргументы передавать конструкторам в зависимости от передаваемого типа.

Я не могу использовать простой if (), потому что компилятор проверит обе подписи, и одна будет неправильной. Я не могу использовать c ++ 17 для «if constexpr () {}».

Я могу передать шаблон Parameter «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> >’

Я упал, что попытка специализировать мой пользовательский код будет адом беспорядка.

Как правильно реализовать вызовы конструктора с возможными переменными сигнатурами?

любые советы будут оценены!

(Ubuntu 16.04, GCC)

1

Решение

Попробуйте метод частичной специализации для достижения этой цели, и я использовал std::make_shared для создания std::shared_ptrs

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::make_shared<T>("test");
}

};

template<>
MyClass<LongConstructorInLibrary>::MyClass()
{
member_p = std::make_shared<LongConstructorInLibrary>(0, 0.0); // pass you values.
}

int main()
{
MyClass<LongConstructorInLibrary> obj;     //works
//MyClass<LongConstructorInLibrary> obj2;   // wrong constructor signature
}
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]