Reputation: 33607
I have a string class:
#include <stdint.h>
class CString {
public:
CString() {}
explicit CString(uint64_t ui64, int width = -1, int base = 10, char fillChar = ' ') {}
CString(const char * str) {}
CString arg(const CString& argument) const {return CString();}
template <typename T>
inline CString arg(T argument, int width = -1, int base = 10, char fillChar = ' ') const
{
return arg(CString(argument, width, base, fillChar));
}
};
Now, I'm using this class:
void main()
{
CString str;
str.arg("123");
}
And get the error:
error C2665: 'CString::CString' : none of the 4 overloads could convert all the argument types
1> source.cpp(6): could be 'CString::CString(uint64_t,int,int,char)'
1> while trying to match the argument list '(const char *, int, int, char)'
1> source.cpp(22) : see reference to function template instantiation 'CString CString::arg<const char*>(T,int,int,char) const' being compiled
1> with
1> [
1> T=const char *
1> ]
Why doesn't arg(CString&)
get called, using the CString(const char *)
constructor?
Upvotes: 0
Views: 261
Reputation: 227578
When you call
str.arg("123");
the best match is obtained via the function template arg
, since CString arg(const CString& argument)
requires a conversion to a user defined type. The function template then calls
return arg(CString(argument, width, base, fillChar));
but there is no CString
constructor that matches the argument list const char*, int, int, char
that you are passing here.
There can be no call to CString(uint64_t, int, int, char)
because the conversion from const char*
to uint64_t
is an invalid conversion. This simplified code sample exhibits the same problem:
#include <cstdint>
void foo(std::uint64_t) {}
int main()
{
foo("hello");
}
error: invalid conversion from 'const char*' to 'uint64_t {aka long long unsigned int}' [-fpermissive]
foo("hello");
If you were to comment out the member function template arg
, then CString arg(const CString& argument)
would be called, via the implicit conversion from const char*
to CString
.
Upvotes: 1
Reputation: 227578
Note: This answers the original question, before it was changed into a different one.
why doesn't template arg overload work?
Because it requires at least two arguments, and you are passing one.
template <typename T>
inline CString arg(T argument, int width, int base = 10, char fillChar = ' ')
{ ... }
Upvotes: 3