Search code examples
c++variadic-templatesvariadic

Error with variadic templates function: candidate expects 0 arguments, 3 provided


I'm trying to write a static variadic templates constructor for my class. But I'm not so experienced in variadic templates and get an error.

I wrote the following code:

template <typename T> struct scalar {

template <typename... Args> static std::shared_ptr<scalar<T>> create(Args &&...args) {
    return std::make_shared<scalar<T>>((std::forward<Args>(args))...);
  }

};


template <typename T>
std::shared_ptr<scalar<T>> operator+(std::shared_ptr<scalar<T>> &lhs,
                                     std::shared_ptr<scalar<T>> &rhs) {
  auto res = scalar<T>::create(lhs->data + rhs->data, {lhs, rhs}, "+");
  res->backward = [lhs, rhs, res]() {
    lhs->grad += res->grad;
    rhs->grad += res->grad;
  };
  return res;
}

and I got that error:

error: no matching function for call to ‘red_engine::scalar<double>::create(red_engine::scalar<double>::value_type, <brace-enclosed initializer list>, const char [2])’
  143 |   auto res = scalar<T>::create(lhs->data * rhs->data, {lhs, rhs}, "*");
      |              ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/alex/projects/AI/nanograd/nanograd-cpp/engine.hpp:36:46: note: candidate: ‘static red_engine::scalar<T>::pointer red_engine::scalar<T>::create(Args&& ...) [with Args = {}; T = double; pointer = std::shared_ptr<red_engine::scalar<double> >]’
   36 |   template <typename... Args> static pointer create(Args &&...args) {
      |                                              ^~~~~~
/home/alex/projects/AI/nanograd/nanograd-cpp/engine.hpp:36:46: note:   candidate expects 0 arguments, 3 provided

Can someone explain me what am I doing wrong? Thank you in advance!


Solution

  • {lhs, rhs} doesn't have a type, so the respective type in Args... can't be deduced, and it seems to make the compiler assume Args is empty, hence candidate expects 0 arguments.

    Use something that does have a type, like MyClass{lhs, rhs} or MyClass(lhs, rhs).