I have some code here
template<typename T, std::size_t size, typename funcType>
struct foo
{
public:
foo(const funcType& func) : m_func(func) {}
~foo() {}
void m_call() { m_func(); }
private:
const funcType& m_func;
T x[size];
};
void printString() { std::cout << "some string\n"; }
I can create an object
foo<int, 3, void(*)()> someObject(printString);
or
foo<int, 3, decltype(printString)> someObject(printString);
but when I try to do this:
foo<int, 3> someObject(printString);
I get this error on g++ 10.2
error: wrong number of template arguments (2, should be 3)
foo<int, 3> someObject(printString);
^
note: provided for 'template<class T, long unsigned int size, class funcType> struct foo'
struct foo
Why cant I do this? Doesn't the compiler know what type printString
is?
And if I change the foo
to
template<typename funcType>
struct foo
{
public:
foo(const funcType& func) : m_func(func) {}
~foo() {}
void m_call() { m_func(); }
private:
const funcType& m_func;
};
I can create it normally
foo someObject(printString);
Am I missing something?
According to cppreference:
Class template argument deduction is only performed if no template argument list is present. If a template argument list is specified, deduction does not take place.
which your last experiment confirms. To deduce funcType
you also need to provide other templated types in constructor to not provide any template argument list.
You can bind other templates with constructor for example using this construct:
#include <iostream>
template<typename T, std::size_t size, typename funcType>
struct foo
{
public:
foo(T (&arr)[size], const funcType& func) : m_func(func) {}
~foo() {}
void m_call() { m_func(); }
private:
const funcType& m_func;
T x[size]{};
};
void printString() { std::cout << "some string\n"; }
void test() {
foo someObject("test", printString);
}