为什么此代码与模板特化有错误

时间:2017-06-20 01:53:52

标签: c++ c++11 variadic-templates template-specialization

我想将一个函数传递参数用于不同的类,所以我使用类模板特化和可变参数函数模板,下面是代码:

#include <iostream>
using namespace std;

template <typename T0, typename T1>
class Package
{
    T0 Data0;
    T1 Data1;
public:
    Package(T0 data0, T1 data1): Data0(data0), Data1(data1) {}
    void Display()
    {
        cout << Data0 << " " << Data1 << endl;
    }
};

template <typename T0>
class Package<T0, void>
{
    T0 Data0;
public:
    Package(T0 data0): Data0(data0) {}
    void Display()
    {
        cout << Data0 << endl;
    }
};

template <>
class Package<void, void>
{
public:
    Package() {}
    void Display()
    {
        cout << "have no member" << endl;
    }
};

template <typename... Args>
void Post(Args... args)
{
    Package<Args...> pak = Package<Args...>(args...);
    pak.Display();
}

int main()
{
    int x = 5;
    float y = 0.9;
    Post(x, y);
    Post(x);
    Post();
    return 0;
}

我有这个错误:

 In instantiation of 'void Post(Args ...) [with Args = {int}]': 
 52:15: required from here 
 43:26: error: wrong number of template arguments (1, should be 2) 
 5:11: error: provided for 'template<class T0, class T1> class Package' 
 43:26: error: wrong number of template arguments (1, should be 2) 
 5:11: error: provided for 'template<class T0, class T1> class Package' 
 In instantiation of 'void Post(Args ...) [with Args = {}]': 
 53:14: required from here 
 43:26: error: wrong number of template arguments (0, should be 2) 
 5:11: error: provided for 'template<class T0, class T1> class Package' 
 43:26: error: wrong number of template arguments (0, should be 2) 
 5:11: error: provided for 'template<class T0, class T1> class Package'

包可以采用2/1/0参数,Post可以提供2/1/0参数,但为什么会出现这个错误?感谢。

3 个答案:

答案 0 :(得分:2)

尝试将默认模板参数添加到Package

template <typename T0 = void, typename T1 = void>
class Package

答案 1 :(得分:0)

  

包可以采用2/1/0参数,Post可以提供2/1/0参数,但为什么会出现此错误?

专业化帮助编译器确定在实例化模板时使用哪一个。

如果您使用

Package<void, void> p1;

使用最后一个专门化。如果你使用

Package<int, void> p1;
Package<double, void> p2;

使用第一个专业化。

如果您使用

Package<int, float> p1;
Package<double, char> p2;

使用原始类模板。

但是,无论使用哪一个,您仍然需要两个模板参数。

如果您希望能够使用

Package<int> p1;

您必须为the other answer建议的第二个参数提供默认类型。

template <typename T0 = void, typename T1 = void>
class Package { ... };

答案 2 :(得分:0)

您使用的是void而不是类型,您可以将班级更改为:

template <typename ...Ts> class Package;

template <typename T0, typename T1>
class Package<T0, T1>
{
    T0 Data0;
    T1 Data1;
public:
    Package(T0 data0, T1 data1): Data0(data0), Data1(data1) {}
    void Display() const
    {
        std::cout << Data0 << " " << Data1 << std::endl;
    }
};

template <typename T0>
class Package<T0>
{
    T0 Data0;
public:
    explicit Package(T0 data0) : Data0(data0) {}

    void Display() const
    {
        std::cout << Data0 << std::endl;
    }
};

template <>
class Package<>
{
    void Display() const { std::cout << "have no member" << std::endl; }
};