【问题标题】:why this code has error with template specialization为什么此代码在模板专业化方面有错误
【发布时间】:2017-11-22 09:05:30
【问题描述】:

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

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

Package可以带2/1/0个参数,Post可以带2/1/0个参数,但是为什么会出现这个错误?谢谢。

【问题讨论】:

  • Package 特化的构造函数的“组合”(不是重载集,因为它们属于不同的类型)可以采用 2/1/0 个参数,但 Package 类模板它本身总是有两个模板参数。也就是说,即使没有可变参数函数,Package&lt;int&gt; 也是非法的。请参阅@max66 的解决方案。

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


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    您使用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; }
    };
    

    【讨论】:

      【解决方案3】:

      Package可以带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 { ... };
      

      【讨论】:

        猜你喜欢
        • 2013-03-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多