Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为甚么康斯特&;as_const的重载已删除?_C++_Templates_Constants_C++17 - Fatal编程技术网

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
的已删除重载无关。