当模板 return 类型阻止它实例化时,如何向用户提供 nice static_assert 消息?

How to give nice static_assert message to users when the template return type prevents it from instantiation?

假设我想编写 returns 指针指向非空容器的第一个元素的函数。

// REQUIRES: c not empty
template<typename C>
auto pointer_to_first(C& c) -> decltype( &(*c.begin()) ){
    return nullptr; // TODO: implement
}

如果我尝试将其与 vector<bool>

一起使用
vector<bool> vb{false, false, true};
pointer_to_first(vb);

编译器给出的错误信息让初学者感到困惑:

error: taking address of temporary [-fpermissive] auto pointer_to_first(C& c) -> decltype(&(*c.begin())){

这很令人困惑,因为初学者不知道 vector<bool> 使用的代理并且 vb 不是临时的。

所以我想补充static_assert容器不能是vector<bool>,容器必须有begin()end()... 我知道该怎么做,但问题是由于重载解析失败,用户只会看到编译器错误消息。

有办法解决这个问题吗?

在我们有概念之前,您可以添加一个额外的层以允许 static_assert 并避免 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);
}