C ++ шаблон конструктора - PullRequest
100 голосов
/ 18 октября 2010

Я хочу иметь не шаблонный класс с конструктором шаблона без аргументов.

Насколько я понимаю, его невозможно (потому что он конфликтует с конструктором по умолчанию - я прав? ), , и обходной путь следующий:

class A{
   template <typename U> A(U* dummy) {
   // Do something
   }
};

Может быть, есть лучшая альтернатива для этого (или лучший обходной путь)?

Ответы [ 8 ]

92 голосов
/ 18 октября 2010

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

Foo<int> f = Foo<int>();

<int> - это список аргументов шаблона для типа Foo, а не для его конструктора.К списку аргументов шаблона конструктора никуда не деться.

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

32 голосов
/ 18 октября 2010

Вы можете создать шаблонную фабричную функцию:

class Foo
{
public:
    template <class T> static Foo* create() // could also return by value, or a smart pointer
    {
        return new Foo(...);
    }
...        
};
23 голосов
/ 18 октября 2010

Насколько я понимаю, его невозможно (потому что он конфликтует с конструктором по умолчанию - я прав?)

Вы не правы. Это никак не противоречит. Вы просто не можете назвать это когда-либо.

15 голосов
/ 18 октября 2010

Некоторые баллы:

  • Если вы объявите любой конструктор (включая шаблонный один), компилятор будет воздерживаться от объявив конструктор по умолчанию.
  • Если вы не объявляете конструктор копирования (для класса X один что займет X или X& или X const &), компилятор сгенерирует конструктор копирования по умолчанию.
  • Если вы предоставляете конструктор шаблона для класса X, который принимает T const & или T или T& тогда тем не менее, компилятор сгенерирует по умолчанию не шаблонно конструктор копирования, даже если вы думаете, что это не так, потому что когда T = X, объявление совпадает с объявлением конструктора копирования.
  • В последнем случае вы можете указать не шаблонный конструктор копирования наряду с шаблонным конструктором. Они не будут конфликтовать. Когда X передан, будет вызываться нетэмплированный. В противном случае шаблон

НТН

14 голосов
/ 24 июля 2015
template<class...>struct types{using type=types;};
template<class T>struct tag{using type=T;};
template<class Tag>using type_t=typename Tag::type;

вышеупомянутые помощники позволяют вам работать с типами как значениями.

class A {
  template<class T>
  A( tag<T> );
};

тип tag<T> - это переменная без состояния, кроме типа, который он содержит.Вы можете использовать это, чтобы передать значение чистого типа в функцию шаблона и получить тип, определяемый функцией шаблона:

auto a = A(tag<int>{});

Вы можете передать более одного типа:

class A {
  template<class T, class U, class V>
  A( types<T,U,V> );
};
auto a = A(types<int,double,std::string>{});
2 голосов
/ 16 октября 2016

Вы можете сделать это:

class C 
{
public:
    template <typename T> C(T*);
};
template <typename T> T* UseType() 
{
    static_cast<T*>(nullptr);
}

Затем создать объект типа C, используя int в качестве параметра шаблона для конструктора:

C obj(UseType<int>());

Так как выне может передать параметры шаблона конструктору, это решение по существу преобразует параметр шаблона в обычный параметр.Использование функции UseType<T>() при вызове конструктора дает понять, кто смотрит на код, что целью этого параметра является сообщить конструктору, какой тип использовать.

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

0 голосов
/ 10 октября 2014

Вот обходной путь.

Создайте шаблонный подкласс B в A. Сделайте независимую от аргумента шаблона часть конструкции в конструкторе A.Выполните зависимую от аргумента шаблона часть в конструкторе B.

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

попробуйте сделать что-то вроде

template<class T, int i> class A{

    A(){
          A(this)
    }

    A( A<int, 1>* a){
          //do something
    }
    A( A<float, 1>* a){
         //do something
    }
.
.
.
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...