簡體   English   中英

為什么指針類型沒有 std::as_const 重載

[英]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;
}

編輯:論文P0007R1std::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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM