Adding this additional overload should work (untested):
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 the = delete
makes it a compile time error. Alternatively, if you want to specify a custom message, you could go for
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, // always false
"No rvalue references allowed!");
}
The std::is_same
is there to make the static_assert
dependent on the template parameter, otherwise it would 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); // OK
foo('x'); // Compiler error
}
MSVC gives the following error here 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 then the program compiles.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…