Jiew Meng
Jiew Meng

Reputation: 88207

C++ Template Function string type not matching?

I have a function defined:

template<class T> 
inline void _assert(const string& message, T expected, T actual);

I have been using it to assert 2 integers are equals. But when I had:

_assert("Modifies(15, v) for v value", "h", varTable->getVarName(list.at(0)));
                                            ^ returns std::string

It doesn't work:

Error   1   error C2782: 'void _assert(const std::string &,T,T)' : template parameter 'T' is ambiguous  h:\dropbox\sch\cs3202\code\test\testqueryevaluator\testgetcandidatelist.cpp 183

Why? 2 strings are not of the same type?

Upvotes: 0

Views: 528

Answers (2)

Andy Prowl
Andy Prowl

Reputation: 126442

Your function getVarName() returns an std::string, but the second argument you supply to _assert() is of type const char[] (decays to const char*).

The two types are not identical, and therefore type deduction cannot find a valid match for T.

To fix it, you could wrap your string literal "h" into an std::string object:

_assert(
    "Modifies(15, v) for v value", 
    string("h"), // <== Wrap the string literal
    varTable->getVarName(list.at(0))
    );

Or you could just modify your _assert() function template so that it does not force the expected and actual value to be of the same type:

template<typename T, typename Y> 
inline void _assert(const string& message, T expected, U actual);

Beware though: if you are using equality comparison (operator ==) inside _assert to compare the expected and the actual value, make sure your T and U are not deduced to be const char* if you want to compare strings; otherwise, your comparison will not do what you expect.

Upvotes: 2

Tony The Lion
Tony The Lion

Reputation: 63200

Your problem is that "h" is of type const char* and your second parameter is of type std::string so it cannot figure out which you want.

You should make them the same type:

_assert("Modifies(15, v) for v value", std::string("h"), varTable->getVarName(list.at(0))); 

or change your function to take two different params:

template<class T, class U> 
inline void _assert(const string& message, T expected, U actual);

Upvotes: 0

Related Questions