C++: использование пакета параметров в конструкторах?

#include <iostream>

class A 
{
    public: 

    A(bool b, int i)
        : b_(b) , i_(i) {}

    void print()
    {
        std::cout << b_ << " " << i_ << "\n"; 
    }

    private:

        bool b_;
        int i_;
};

class B 
{
    public: 

    B(double d)
        : d_(d) {}

    void print()
    {
        std::cout << d_ << "\n"; 
    }

    private:

        double d_;
};

template<class T=A, typename ... Args>
void f(int a, Args ... args)
{
    std::cout << a << std::endl;
    T t(args...);
    t.print();
}

int main()
{
    f(1,false,3);
    f<A>(2,true,1);
    f<B>(3,2.0);
}

Приведенный выше код компилируется и работает нормально. Но:

// (class A and B declared as above)   

template<class T, typename ... Args>
class F 
{
 public:
  F(int a, Args ... args)
  {
    std::cout << a << std::endl;
    T t(args...);
    t.print();
  }
};

int main()
{
    F<A>(4,true,1);
    F<B>(5,2.0);
}

не удается скомпилировать с сообщением:

main.cpp: в функции 'int main()': main.cpp:64:18: ошибка: нет соответствующей функции для вызова 'F::F(int, bool, int)' F(4,true,1);

3 ответа

Решение

С вашим текущим кодом ваш экземпляр F<A> делает Argsаргумент шаблона пуст, что означает, что у конструктора есть толькоa аргумент, а не args.

Кажется, вы хотите, чтобы только конструктор имел пакет параметров шаблона, а не весь класс:

template<class T>
class F 
{
 public:
  template<typename ... Args>
  F(int a, Args ... args)
  {
    std::cout << a << std::endl;
    T t(args...);
    t.print();
  }
};

В зависимости от ваших потребностей это должно быть:

template<class T, typename ... Args>
class F 
{
 public:
  F(int a, Args ... args)
  {
    std::cout << a << std::endl;
    T t(args...);
    t.print();
  }
};

int main()
{
    F<A, bool, int>(4,true,1);
    F<B, double>(5,2.0);
}

или

template<class T>
class F 
{
 public:
  template <typename ... Args>
  F(int a, Args ... args)
  {
    std::cout << a << std::endl;
    T t(args...);
    t.print();
  }
};

int main()
{
    F<A>(4,true,1);
    F<B>(5,2.0);
}

Вы сделали класс шаблоном, а не конструктором.

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

Это не работает.

Вместо этого вы можете сделать конструктор шаблоном, а не классом.

Другие вопросы по тегам