Шаблон конструктора - PullRequest
       25

Шаблон конструктора

2 голосов
/ 08 декабря 2011

У меня есть класс с несколькими конструкторами.В соответствии с параметром, который передается через argv в main (), я хотел бы переключаться между различными конструкторами.Следующий упрощенный пример прекрасно работает в случае, когда «obj» заменен на класс, и я использую, например, obj1-> int и obj2-> double.Но что мне нужно изменить, чтобы следующий код выполнялся с использованием enum?

#include<iostream>

using namespace std;

enum obj{obj1,obj2};

template <obj T>
class A
{
public:
  A(T);

private:
  T t_;
};

template<obj T>
A<T>::A(T )
{}

template<>
A<obj1>::A(obj1 t):t_(t) {cout<<"case 1"<< endl;}

template<>
A<obj2>::A(obj2 t):t_(t) {cout<<"case 2"<< endl;}

int main()
{
    obj test=obj1;
    A<obj> a(test);
    return 1;
}

Спасибо за вашу помощь!

РЕДАКТИРОВАТЬ: Ясно, что код неправильный в отношении типа / значения, но какой механизм может напоминать такое переключение конструкторов?

Ответы [ 4 ]

3 голосов
/ 08 декабря 2011

Вы должны специализироваться на типах, а не на значениях.Если вы знаете значение во время компиляции, вы можете использовать boost::mpl::int_ для этого.Если вы этого не сделаете (как в вашем случае), вам придется жить с простым старым if.

1 голос
/ 08 декабря 2011

Я думаю, что вы хотели сделать следующее:

#include<iostream>

enum obj{obj1,obj2};

template<obj>
class A
{
public:
    A();

private:
    obj t_;
};

template<obj x>
A<x>::A() : t_(x){}

template<>
A<obj1>::A() : t_(obj1){ std::cout << "obj1\n"; }

template<>
A<obj2>::A() : t_(obj2){ std::cout << "obj1\n"; }

int main()
{
    const obj x = obj1; //  can only be used as the template argument below because it's a compile time constant
    A<x> a;

    return 0;
}

Однако это работает, только если вы хотите «включить» константу времени компиляции, и звучит так, как будто вы этого не делаете.Вам необходимо использовать условие времени выполнения (if, switch и т. Д.).

1 голос
/ 08 декабря 2011

Вы неправильно подходите к проблеме. Шаблоны создаются во время компиляции, поэтому вы не можете выбрать специализацию на основе значения, которое присутствует во время выполнения. Помимо других ошибок в вашем коде, это решение не будет работать.

Распространенным решением этой проблемы (создание различных объектов на основе параметра) является абстрактный фабричный шаблон . Это означает, что вы перемещаете логику условного конструирования в фабричный класс и используете виртуальные методы, чтобы избежать необходимости писать другой код на вызывающей стороне (так что по сути вы используете полиморфизм).

0 голосов
/ 08 декабря 2011

Вы должны сделать что-то вроде этого:

enum E
{
    A,
    B
};

template<E e>
struct A
{
};

template<>
struct A<E::A>
{
};

template<>
struct A<E::B>
{
};

int main()
{
    A<E::B> ab;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...