[英]Avoiding to defer “child” object construction with `operator<<`
假設我有一個容器對象,它存儲了多態子的std::vector
。
struct Child
{
Child(Parent& mParent) { /* ... */ }
virtual ~Child() { }
};
class Parent
{
private:
std::vector<std::unique_ptr<Child>> children;
template<typename T, typename... TArgs>
auto& mkChild(TArgs&&... mArgs)
{
// `static_assert` that `T` is derived from `Child`...
children.emplace_back(std::make_unique<T>(std::forward<TArgs>(mArgs)...));
return *children.back();
}
public:
template<typename T, typename... TArgs>
auto& add(TArgs&&... mArgs)
{
mkChild<T>(std::forward<TArgs>(mArgs)...));
return *this;
}
};
現在我可以像這樣使用Parent
類:
int main()
{
Parent p;
p.add<Child1>(some_args1).add<Child2>(some_args2);
}
雖然這種語法實現了我想做的事情(將子項添加到單個父項中),但我覺得很難閱讀,特別是在我的實際用例中。
我真的想用operator<<
代替。 但我無法想出一種方法來構建孩子。
// Desired syntax
int main()
{
Parent p;
p << mk<Child1>(some_args1) << mk<Child2>(some_args2);
}
請注意我從未在mk
函數中指定父級。
我不想說mk<Child1>(p, some_args1)
。 編譯器應該從operator<<
的鏈接中找出p
。
有沒有什么方法可以實現這個mk
函數生成代碼等於通過.add<T>(...)
鏈接生成的代碼?
我設法實現這一點的唯一方法是使用一個中間人結構,該結構包含子類的構造可變參數。
template<typename T, typename... TArgs> struct DeferCtor
{
std::tuple<TArgs...> ctorArgs;
};
然后operator<<(DeferCtor<T, TArgs...>&)
將處理Parent
對象的構造。
有沒有辦法避免這一步,同時仍然有所需的語法? (不在mk
函數中傳遞父實例。)
您並沒有真正在現有代碼中創建對象 - 您使用unique_ptr
在堆上創建子對象,然后將該unique_ptr
移動到父對象中。 您可以對您的operator<<
執行相同的operator<<
如果您只是將其定義為使用unique_ptr
:
Parent &Parent::operator<<(std::unique_ptr<Child> ch) {
children.emplace_back(std::move(ch)); }
現在假設你的mk
全局函數基本上只是make_unique
的別名:
template<typename T, typename... TArgs>
std::unique_ptr<T> mk(TArgs&&... mArgs) {
return std::make_unique<T>(std::forward<TArgs>(mArgs)...)); }
你應該能夠使用你想要的語法。
(根據我之前的評論)。 我建議你構造base_ptr的base並將其提供給opertor<<
(ideone link) 。 無需花哨或復雜。
using namespace std;
using mk = make_unique;
#include <memory>
#include <iostream>
class B {};
class D : public B {};
class E : public B {};
class A {
public:
A & operator << ( std::unique_ptr<B> bp){
std::cout << " added a value " << std::endl;
// children.push_back(move(bp));
return *this;
}
};
int main() {
// your code goes here
A a;
a << mk<D>( .. some argument ) << mk<E>( other arguments) ;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.