我刚刚遇到std::as_const,并对以下代码片段中最后一行的输出感到惊讶:
#include <cstdio>
#include <utility>
struct S {
void foo() { std::puts("foo: non const"); }
void foo() const { std::puts("foo: const"); }
};
int main() {
S s;
s.foo(); // foo: non const
std::as_const(s).foo(); // foo: const
auto* s_ptr = &s;
s_ptr->foo(); // foo: non const
std::as_const(s_ptr)->foo(); // foo: non const (?)
}
Run Code Online (Sandbox Code Playgroud)
查看文档,我明白为什么调用
非const重载:返回 a ,即对非常量的常量指针的引用,而不是如我所料的a ,即指向常量的指针。foostd::as_const(s_ptr)S* const&SS const*S
所以,我的问题是为什么标准不提供std::as_const指针类型的重载?例如:
template <class T>
constexpr std::add_const_t<T>* as_const(T* t) noexcept {
return t;
}
Run Code Online (Sandbox Code Playgroud)
编辑:std::as_const论文P0007R1的动机之一是选择函数重载,而不必求助于const_cast. P0007R1 提供了以下示例:
int processEmployees( std::vector< Employee > &employeeList );
bool processEmployees( const std::vector< Employee > &employeeList );
Run Code Online (Sandbox Code Playgroud)
较大的项目通常需要调用函数,例如
processEmployees,并在特定const或非const重载之间进行选择。[...]
这就是为什么我感到惊讶的是,当应用于我发布的代码中的指针时,它对重载解析没有帮助,也没有:
std::as_const(this)->foo();
Run Code Online (Sandbox Code Playgroud)
也不选择以下重载中的后者:
int processEmployees( std::vector< Employee > *employeeList );
bool processEmployees( const std::vector< Employee > *employeeList );
Run Code Online (Sandbox Code Playgroud)
的目的std::as_const是能够将非左const值引用为const左值,以便它在使用它的上下文中不可修改。换句话说std::as_const(x)应该是写作的简写
const auto& y = x;
Run Code Online (Sandbox Code Playgroud)
然后使用y.
它已经做得很好了,所以指针不需要特殊的行为。
这是一个简单的例子,其中建议的额外过载会产生严重的负面影响:
std::vector<int> vec = /*...*/;
for(auto it = std::begin(vec); it != std::end(vec); it++)
func(std::as_const(it));
Run Code Online (Sandbox Code Playgroud)
这里的目的是确保函数func不能修改it,因为迭代向量的责任在于循环for。如果func只是按值或const引用获取迭代器,则std::as_const不是严格要求的,但无论如何作为一种安全措施,它是有意义的,或者因为存在多个重载func,其中一些重载确实修改了它们的参数。
auto这是一些迭代器类型。它可能是一个指针。或者它可能是一个类类型。根据您建议的重载,as_const这会中断,具体取决于std::vector迭代器的实现方式。
std::as_const(it)应该说it不得通过这种使用进行修改。它不应该说明对象it引用是否可修改。这不是它的目的。当然,添加一个使引用的对象不可修改的函数是有意义的。但是它应该有一个不同的名称,并且您可能希望为任意迭代器而不是专门的指针实现它。基本上,是一个迭代器到const迭代器的适配器。
| 归档时间: |
|
| 查看次数: |
363 次 |
| 最近记录: |