Reputation: 10967
I am currently struggling to get the following code to compile. First the header file containing a class with a method template:
// ConfigurationContext.h
class ConfigurationContext
{
public:
template<typename T> T getValue(const std::string& name, T& default) const
{
...
}
}
Somewhere else I want to call this method like this:
int value = context.getValue<int>("foo", 5);
There I get the following error:
error: no matching function for call to 'ConfigurationContext::getValue(const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, int)'
I checked the obvious errors like missing includes and stuff like that. But everything seems to be right. I tried removing the pass-by-reference of the template type argument like this:
template<typename T> T getValue(const std::string& name, T default) const ...
Then it compiles without any errors and also runs fine, but I'd still like to pass in a reference here...
Does anybody know whats happening here and how to make this work?
Upvotes: 2
Views: 7803
Reputation: 224079
5
is a literal, and you cannot bind literals to non-const
references. Either take T
per copy or per const
reference:
template<typename T> T getValue(const std::string& name, const T& def) const
(BTW, I doubt that your compiler accepts T default
, because default
is a keyword and must not be used as an identifier.)
The reason you cannot do this is because taking arguments per non-const
reference usually implies that the callee might change the value and such changes should reflect at the caller's. (See How to pass objects to functions in C++?) However, you cannot change literals or temporaries. So you are not allowed to pass them to non-const
references.
Upvotes: 9