Let's assume that I want to write function that returns pointer the first element of nonempty container.
// REQUIRES: c not empty
template<typename C>
auto pointer_to_first(C& c) -> decltype( &(*c.begin()) ){
return nullptr; // TODO: implement
}
If I try to use this with vector<bool>
vector<bool> vb{false, false, true};
pointer_to_first(vb);
Compiler gives error message confusing to beginners:
error: taking address of temporary [-fpermissive] auto pointer_to_first(C& c) -> decltype(&(*c.begin())){
It is confusing since beginners do not know about proxy that vector<bool>
uses and vb
is not a temporary.
So I wish to add static_assert
s that the container can not be vector<bool>
, also that container must have begin()
, end()
...
I know how to do that but the problem is that since overload resolution fails users will only see the compiler error message.
Is there a way to get around this?
Until we have concept, you may add an extra layer to allow to have static_assert
and avoid SFINAE:
// Your SFINAE function:
template<typename C>
auto pointer_to_first_impl(C& c) -> decltype(&(*c.begin())){
return nullptr;// TODO: implement
}
template<typename C>
decltype(auto) pointer_to_first(C& c)
{
// You need to implement the traits for the check
static_assert(my_cond<C>::value, "type is incorrect");
return pointer_to_first_impl(c);
}