簡體   English   中英

C ++模板允許丟棄const引用限定符

[英]C++ template allows discard of const reference qualifier

為什么這段代碼會編譯? (用g ++和clang ++測試)

以下代碼用於接受函數並從中創建轉發std :: function的工廠方法。 如您所見,lambda內部接受const Arg& arguments並將它們轉發給給定的函數。

main()我使用factory()test_func()創建一個轉發器,它接受一個非const引用參數。 我不明白的是為什么這不會產生關於從參數中丟棄const限定符的錯誤。

請注意,確實在main()創建的類C的實例在不創建任何副本的情況下傳遞。

#include <functional>
#include <iostream>

class C
{
public:
        C() {}

        C(const C&)
        {
                std::cout << "C copy\n";
        }
};

int test_func(C& cref)
{
        return 0;
}

template<typename Ret, typename... Arg>
std::function<Ret (const Arg&...)> factory(Ret (*func) (Arg...))
{
        return [ func ] (const Arg&... arg) -> Ret {
                return (func)(arg...);
        };
}

int main() {
        auto caller = factory(test_func);
        C c;
        caller(c);
        return 0;
}

正如評論中所提到的,您應該使用完美轉發(請參閱Scott Meyers關於Universal參考的演示文稿)。

在你的情況下,它應該是:

#include <functional>
#include <iostream>
#include <utility>

class C
{
public:
        C() {}

        C(const C&)
        {
                std::cout << "C copy\n";
        }
};

int test_func(const C& )
{
        return 0;
}

template<typename Ret, typename... Arg>
std::function<Ret (Arg...)> factory(Ret (*func) (Arg...))
{
        return [ func ] (Arg&&... arg) -> Ret {
                return func(std::forward<Arg>(arg)...);
        };
}

int main() {
        auto caller = factory(test_func);
        const C c;
        caller(c);
}

請注意我改變了C c; const C c; 在你的main() ,我修改了test_func。


如果要避免創建副本,則必須確保test_func函數不按值獲取。 它應該通過引用(非const的const)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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