当模板返回类型阻止它实例化时,如何给用户提供很好的static_assert消息?

问题描述:

我们假设我想写返回指针非空容器的第一个元素的函数。当模板返回类型阻止它实例化时,如何给用户提供很好的static_assert消息?

// 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 s表示容器不能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); 
}