Yuriy
Yuriy

Reputation: 83

Using class constructor as callable object

class C {
public:
    C() {}
};

template<typename T>
void func(T f) {}

int main() {
    func(C);
}

How to fix the compilation error "2.cpp:9:15: error: expected primary-expression before ‘)’ token func(C);"?

Passing class as parameter seems ridiculous, but I want to compile function like thread, since "thread(C)" works fine:

#include <thread>

class C {
public:
    C() {}
};

template<typename T>
void func(T f) {}

int main() {
    std::thread(C);
}

Upvotes: 8

Views: 992

Answers (1)

yeputons
yeputons

Reputation: 9238

Unfortunately, one cannot take address of a constructor in C++. Meaning, you cannot simply take "a pointer to constructor" and use it as a functor (like you'd do with free function or member function).

You actually cannot "pass a class" as a parameter, because C++ core does not have reflection and if you get "a class" in runtime, you cannot do anything with it. You can only "pass a class" as a template parameter.

What you can do, though, is simply use lambda function which will call the corresponding constructor:

class C {
public:
    C() {}
};

template<typename T>
void func(T f) {
  auto c_instance = f();
}

int main() {
    func([](){ return C(); });
}

Note that you still do not pass anything in runtime - return type of the lambda [](){ return C(); } is known in compile-time, therefore the type of auto c_instance is also known in compile-time.

However, I think that if you don't need to pass any other factories for C into func, simply creating the instance inside func would be clearer:

class C {
public:
    C() {}
};

template<typename T>
void func() {
  T c_instance;
}

int main() {
    func<C>();
}

Regarding std::thread(c);

std::thread(C);

is not a function call. std::thread is a type. Therefore, it declares a local variable named C. Using

auto a = std::thread(C);

should produce a similar compiler error.

Upvotes: 10

Related Questions