Специализация конструктора с шаблонами - PullRequest
1 голос
/ 01 апреля 2019
#include <iostream>

using namespace std;

template <class T>
struct MyType
{
    public:

    T cont;

    MyType(T value) : cont(value) {}
    MyType(int value = 1) : cont(value) {}
    MyType(double value = 1.2) : cont(value) {}
};

int main()
{
    MyType <int> a;

    return 0;
}

Этот код выдает следующие ошибки:

ошибка: «MyType :: MyType (int) [with T = int]» не может быть перегружена

ошибка: с'MyType :: MyType (T) [with T = int]'

Теперь, как я могу специализировать некоторый конструктор, предоставляя им параметры по умолчанию?

EDIT:

Мне нужен способ сделать это без копирования всех классов для каждой специализации.

Ответы [ 2 ]

2 голосов
/ 01 апреля 2019

Более простой, вероятно, будет специализация:

template <class T>
struct MyType
{
public:
    T cont;

    MyType(T value) : cont(value) {}
};

template <>
struct MyType<int>
{
public:
    int cont;

    MyType(int value = 1) : cont(value) {}
};

template <>
struct MyType<double>
{
public:
    double cont;

    MyType(double value = 1.1) : cont(value) {}
};

Или, так как кажется, что вас интересует только значение по умолчанию, вы можете пометить диспетчерское значение по умолчанию:

template <typename T> struct tag{};

template <typename T> const T defaultValue(tag<T>) { return {}; }
inline int defaultValue(tag<int>) { return 1;}
inline double defaultValue(tag<double>) { return 1.1;}

template <class T>
struct MyType
{
public:
    T cont;

    MyType(T value = defaultValue(tag<T>)) : cont(value) {}
};
2 голосов
/ 01 апреля 2019

Doing

template <class T>
struct MyType
{
    public:

    T cont;

    MyType(T value) : cont(value) {}
    MyType(int value = 1) : cont(value) {}
    MyType(double value = 1.2) : cont(value) {}
};

int main()
{
    MyType <int> a;

    return 0;
}

у вас есть два идентичных конструктора MyType(int value = 1) и MyType(T/*int*/ value), вы не можете иметь эту перегрузку


Мне нужен способ сделать это без копирования всех классов для каждой специализации.

Вы можете иметь

#include <iostream>

using namespace std;

template <class T>
struct MyType
{
  public:
    T cont;

    MyType(T value = 1) : cont(value) {}
};

template<>
MyType<int>::MyType(int value) : cont(value + 1) {}

template<>
MyType<double>::MyType(double value) : cont(value + 2) {}

int main()
{
  MyType <int> a;
  MyType <int> aa(10);
  MyType <double> b;

  cout << a.cont << '/' << aa.cont << '/' << b.cont << endl;

  return 0;
}

но вы не можете указать другое значение по умолчанию для параметра специализации (error: default argument specified in explicit specialization [-fpermissive]), поскольку, как обычно, значение по умолчанию указано в объявлении, а не в определении

Компиляция и исполнение

pi@raspberrypi:/tmp $ g++ -pedantic -Wextra -Wall t.cc
pi@raspberrypi:/tmp $ ./a.out
2/11/3
...