C ++: используя пакет параметров в конструкторах? - PullRequest
0 голосов
/ 13 февраля 2020
#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 ]

3 голосов
/ 13 февраля 2020

В вашем текущем коде экземпляр 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();
  }
};
1 голос
/ 13 февраля 2020

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

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);
}
1 голос
/ 13 февраля 2020

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

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

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

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

...