Adding this extra overload should work (unchecked):
template <class Collection> const typename Collection::value_type::second_type& FindWithDefault(const Collection& collection, const typename Collection::value_type::first_type& key, const typename Collection::value_type::second_type&& value) = delete;
Overload resolution will select this overload for rvalue references, and = delete will make it a compile-time error. Alternatively, if you want to specify a custom message, you can go to
template <class Collection> const typename Collection::value_type::second_type& FindWithDefault(const Collection& collection, const typename Collection::value_type::first_type& key, const typename Collection::value_type::second_type&& value) { static_assert( !std::is_same<Collection, Collection>::value,
std::is_same is to make static_assert dependent on the template parameter, otherwise it will cause a compilation error even when the overload is not called.
EDIT: Here is a minimal complete example:
void foo(char const&) { }; void foo(char const&&) = delete; int main() { char c = 'c'; foo(c);
MSVC gives the following error for the second call to foo :
rval.cpp(8) : error C2280: 'void foo(const char &&)' : attempting to reference a deleted function rval.cpp(2): See declaration of 'foo'
The first call, however, works fine, and if you comment out the second, the program compiles.
source share