C++ 为甚么康斯特&;as_const的重载已删除?
我在一封信中读到如下内容:C++ 为甚么康斯特&;as_const的重载已删除?,c++,templates,constants,c++17,C++,Templates,Constants,C++17,我在一封信中读到如下内容: P0007提出了一个助手函数模板作为常量,该模板 获取引用并将其作为对const的引用返回 template <typename T> std::add_const_t<T>& as_const(T& t) { return t } template <typename T> void as_const(T const&&) = delete; template std::add_const_t&a
P0007
提出了一个助手函数模板作为常量
,该模板
获取引用并将其作为对const
的引用返回
template <typename T> std::add_const_t<T>& as_const(T& t) { return t }
template <typename T> void as_const(T const&&) = delete;
template std::add_const_t&as_const(t&t){return t}
模板无效为_const(T const&&)=删除;
为什么要删除
常量和&
重载?考虑如果没有该重载会发生什么,并尝试传入常量
右值:
template <typename T> const T &as_const(T &t) { return t; }
struct S { };
const S f() { return S{}; }
int main() {
// auto & ref = as_const(S()); // correctly detected as invalid already
auto & ref = as_const(f()); // accepted
}
template const T&as_const(T&T){return T;}
结构S{};
常量sf(){返回S{};}
int main(){
//auto&ref=as_const(S());//已正确检测为无效
auto&ref=as_const(f());//已接受
}
这是可以接受的,因为
T
将被推断为const S
,并且临时变量可以绑定到const S&
。结果是您意外地得到了一个临时的左值引用,它将在初始化ref
后立即被销毁。几乎所有使用左值(无论是变量还是函数参数)的用户都不希望传递临时值;默默地接受临时职位意味着你很容易默默地得到悬而未决的推荐信。@dyp是的,没错,否则就不会有问题了。:)也许我应该在这一点上做进一步的阐述。谢谢T.C.的编辑顺便说一句,我最初有一个带有xvalue的示例,但在简化示例时忘记了更新文本。是的,我的评论更多的是作为对您答案的进一步解释。我不确定这个限制是否有用as_const(T const&&
可以简单地返回一个T const&
,并且编译器警告将T const&
变量绑定到变量定义中的T const&
不会延长生存期。@dyp然后可能只会有一个as_const(T&&
(那里没有const
)它返回T const&
重载。是的,这是可能的,但我怀疑调用作为常量并传递右值更可能是一个错误,而不是需要支持的东西。在动机方面,有一个关于ADL的例子介于void foo(const T&)
和bool foo(T&)
之间,因此,删除的版本不允许在void foo(const t&&)
和bool foo(t&&)
..@Jarod42之间进行选择。我不理解您的评论。据我所知,如果你有一个T&T
,你可以调用foo(T)
(你的第二个重载),或者foo(const_cast(T))
(你的第一个重载)。动机部分介绍了as_const
的基本用法:可以编写foo(as_const(t))
来获得第一个重载。它与as_const
的已删除重载无关。