Aelian
Aelian

Reputation: 695

How to 'help' the compiler to deduce function template return type from a template parameter which is a function?

To de-clutter code from strtoxx calls, but still have them inlined, I would like to have a function template like:

template <typename STR_TO_NUM> static auto StrToNum( const string& s ) {
    char* pEnd;
    return STR_TO_NUM( s.c_str(), &pEnd, 10 );
}

And call it like

unsigned long x = StrToNum<strtoul>( "1984" );

However I get 'template argument deduction/substitution failed:' error. I can do:

template <typename T, T (*STR_TO_NUM)(const char *, char **, int)> static T StrToNum( const string& s ) {
    char* pEnd;
    return STR_TO_NUM( s.c_str(), &pEnd, 10 );
}

And specify the return type when calling. But it feels like that is redundant. Is there a way to avoid it?

I tried to 'template typedef' STR_TO_NUM using 'using' in C++11, but couldn't figure out how to do that for function types.

Thanks

Upvotes: 0

Views: 118

Answers (2)

Jarod42
Jarod42

Reputation: 218238

C++17 have:

template <auto STR_TO_NUM>
static auto StrToNum(const string& s) {
    char* pEnd;
    return STR_TO_NUM( s.c_str(), &pEnd, 10 );
}

instead of

template <typename T, T STR_TO_NUM>
static auto StrToNum(const string& s) {
    char* pEnd;
    return STR_TO_NUM( s.c_str(), &pEnd, 10 );
}

and its

StrToNum<decltype(&strtoul), &strtoul>("1984");

Upvotes: 2

Andriy Tylychko
Andriy Tylychko

Reputation: 16276

STR_TO_NUM in your first example is a type. You pass strtoul that is a function. You can try something like:

template <typename STR_TO_NUM> static auto StrToNum( const string& s, STR_TO_NUM strToNum ) {
    char* pEnd;
    return strToNum(s.c_str(), &pEnd, 10 );
}

and call it as:

unsigned long x = StrToNum( "1984", strtoul );

Upvotes: 6

Related Questions