简体   繁体   中英

Why can't I deduce one of the class template arguments?

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);

}

godbolt

Use template function to create the object and to deduct missing template arguments from function call. Something like this.

template<typename T, std::size_t Size, typename FunctionT>
foo<T, Size, FunctionT> create_foo(const FunctionT &func) {
    return foo<T, Size, FunctionT>(func);
} 

auto foo_obj = create_foo<int, 3>(printString);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM