我有一個C++框架,我提供給我的用戶,他們應該使用我用自己的實現編寫的模板包裝作爲模板類型。 包裝器充當RAII類,它包含一個指向用戶類實現的指針。 爲了使用戶的代碼乾淨整潔(在我看來),我提供了一個轉換操作符,它將包裝器轉換爲它所包含的指針。這種方式(以及其他一些重載)用戶可以使用我的包裝,就好像它是一個指針(很像shared_ptr)。C++ std ::移動指針
我遇到了一個角落的情況,用戶調用一個函數,該函數使用指向他的實現類的指針,在我的包裝上使用std :: move。這裏是什麼樣子的例子:
#include <iostream>
using namespace std;
struct my_interface {
virtual int bar() = 0;
};
template <typename T>
struct my_base : public my_interface {
int bar() { return 4; }
};
struct my_impl : public my_base<int> {};
template <typename T>
struct my_wrapper {
my_wrapper(T* t) {
m_ptr = t;
}
operator T*() {
return m_ptr;
}
private:
T* m_ptr;
};
void foo(my_interface* a) {
std::cout << a->bar() << std::endl;
}
int main()
{
my_impl* impl = new my_impl();
my_wrapper<my_impl> wrapper(impl);
foo(std::move(wrapper));
//foo(wrapper);
return 0;
}
[這是ofcourse只是案件的一個例子,有在包裝更多的方法,但我敢肯定,在這裏不發揮作用在這種情況下]
用戶,如我所料,如果在包裝上調用std :: move,那麼在調用foo
之後,包裝將是空的(或者至少像被移動一樣進行修改) ,但實際上在foo
之前調用的唯一方法是演員。
有沒有一種方法,使兩個調用使用和不std::move
打電話時foo
即區分之間的調用foo
?
編輯 得益於鳴叫鴨的評論,我發現一種方式,my_wrapper
知道哪些電話是必需的,但我真的不知道這是一起去的最佳方法,並讚賞這樣的評論,以及:
而不是以前的類型轉換操作符的使用以下兩種:
operator T*() & {
return m_ptr;
}
operator T*() &&{
//Do something
return m_ptr;
}
現在operator T*() &&
用的std ::移動和operator T*() &
打電話時被稱爲沒有它調用時被調用。
您是指在呼叫站點還是被調用者區分? –
被調用者的意思是'my_impl'類型? – ZivS
用戶的期望是不合理的。如果你對某個東西調用了'std :: move',並將它傳遞給一個沒有佔用移動對象的函數,那麼期望這個對象是空的或者更改是不合理的。例如:'std :: shared_ptr foo; ... std :: move(foo) - > bar();'這不應該改變'foo',因爲'bar'不佔有。如果'bar(std :: move(foo));'也是如此。 'std :: move'只是給被調用的函數*權限*來移動對象,如果沒有指定它,它不會強制它移動它。 –