[英]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.