[英]Why no std::as_const overload for pointer types
我剛剛遇到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 (?)
}
查看文檔,我明白為什么調用foo
的非const
重載: std::as_const(s_ptr)
返回S* const&
,即對指向非常量S
的常量指針的引用,而不是S const*
,即指向常量S
的指針,正如我所預料的那樣。
所以,我的問題是為什么標准也不為指針類型提供std::as_const
重載? 例如:
template <class T>
constexpr std::add_const_t<T>* as_const(T* t) noexcept {
return t;
}
編輯:論文P0007R1中std::as_const
的動機之一是選擇函數 oveload 而不必求助於const_cast
。 P0007R1 提供了這個例子:
int processEmployees( std::vector< Employee > &employeeList );
bool processEmployees( const std::vector< Employee > &employeeList );
較大的項目通常需要調用函數,如
processEmployees
,並在特定的const
或非const
重載中進行選擇。 [...]
這就是為什么我有點驚訝它在應用到我發布的代碼中的指針時對重載解決沒有幫助,也不是:
std::as_const(this)->foo();
也不選擇以下重載中的后者:
int processEmployees( std::vector< Employee > *employeeList );
bool processEmployees( const std::vector< Employee > *employeeList );
std::as_const
的目的是能夠將非const
左值引用為const
左值,以便在使用它的上下文中不可修改。 換句話說std::as_const(x)
應該是寫作的簡寫
const auto& y = x;
然后使用y
。
它已經做得很好,因此不需要指針的特殊行為。
這是一個簡單的示例,其中建議的額外過載會產生嚴重的負面影響:
std::vector<int> vec = /*...*/;
for(auto it = std::begin(vec); it != std::end(vec); it++)
func(std::as_const(it));
這里的目的是確保函數func
不能修改it
因為迭代向量的責任在於for
循環。 如果func
僅采用迭代器按值或const
引用,則std::as_const
不是嚴格要求的,但作為安全措施還是有意義的,或者因為func
有多個重載,其中一些確實修改了它們的參數。
auto
這里是一些迭代器類型。 它可能是一個指針。 或者它可能是一個類類型。 使用您建議的as_const
重載,這將取決於std::vector
迭代器的實現方式而中斷。
std::as_const(it)
應該it
不應通過這種使用進行修改。 它不應該it
引用的對象是否是可修改的。 那不是它的目的。 當然,添加一個使引用對象不可修改的函數可能是有意義的。 但這應該有一個不同的名稱,您可能希望為任意迭代器實現它,而不是專門為指針實現。 基本上,一個迭代器到const
迭代器的適配器。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.