带有模板的构造器专业化

时间:2019-04-01 15:14:32

标签: c++ templates constructor specialization

#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]'

现在,我该如何专门为一些构造函数提供默认参数?

编辑:

我需要一种方法,而不必为每个专业化都复制粘贴所有类。

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:2)

更简单的可能是专业化:

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) {}
};