2016-04-03 55 views
0

我希望有一個結構體用轉發參數初始化其成員。這個編譯和工作正常,除非我聲明析構函數,並且當我嘗試從一個函數返回結構(我認爲它需要一個拷貝構造函數)。用declard和參數轉發構造函數隱式複製一個結構體

#include <utility> 

struct Foo 
{ 
    int val; 

    Foo(int val) : val(val) 
    { 
    } 
}; 

struct FooContainer 
{ 
    Foo member; 

    template<typename... Args> 
    FooContainer(Args&&... args) : 
     member(std::forward<Args>(args)...) 
    {} 

    ~FooContainer() {} 
}; 

FooContainer getFooContainer() 
{ 
    FooContainer retval(0); 
    return retval; 
} 

int main() {} 

編譯器錯誤是:

example.cc: In constructor ‘FooContainer::FooContainer(Args&& ...) [with Args = FooContainer&]’: 
example.cc:27: instantiated from here 
example.cc:18: error: no matching function for call to ‘Foo::Foo(FooContainer&)’ 
example.cc:7: note: candidates are: Foo::Foo(int) 
example.cc:4: note:     Foo::Foo(const Foo&) 

它看起來像它試圖產生FooContainer拷貝構造函數,但因爲它沒有一種方法來初始化符失敗。然而,如果我刪除了構造函數或析構函數,它編譯得很好。*爲什麼要這樣做?無論如何,

* on http://cpp.sh/與GCC 4.9.2。即使未聲明析構函數,Ubuntu上的g ++ 4.4.3也會提供相同的錯誤。

+1

望着編譯器錯誤,它看起來好像編譯器不知道是否爲Foo或'Foo(int val)'構造函數調用copy-constructor。嘗試使'Foo(int val)''顯式'。 – user3147395

+0

我做了,它沒有改變任何東西 - 雖然使'FooContainer'構造函數'顯式'做了。謝謝!現在看看它是否解決了我的程序中的所有問題或者其中的一些問題... –

回答

1

我不能確切地告訴你爲什麼會發生這種情況(標準專家將能夠),但問題實際上是由於您定義了用戶定義的析構函數而導致的。

刪除,問題消失(您想使用的規則的歸零呢,對吧?)

如果你必須有析構函數,不能重構它走出於某種原因,然後更換移動構造函數(您通過提供析構函數隱式刪除)也將解決此問題。

解決方案1 ​​ - 0使用規則:

#include <utility> 

struct Foo 
{ 
    int val; 

    Foo(int val) : val(val) 
    { 
    } 
}; 

struct FooContainer 
{ 
    Foo member; 

    template<typename... Args> 
    FooContainer(Args&&... args) : 
    member(std::forward<Args>(args)...) 
    {} 

// ~FooContainer() {} 
}; 

FooContainer getFooContainer() 
{ 
    FooContainer retval(0); 
    return retval; 
} 

int main() {} 

解決方案2 - 5使用規則:

#include <utility> 

struct Foo 
{ 
    int val; 

    Foo(int val) : val(val) 
    { 
    } 
}; 

struct FooContainer 
{ 
    Foo member; 

    template<typename... Args> 
    FooContainer(Args&&... args) : 
    member(std::forward<Args>(args)...) 
    {} 

    FooContainer(const FooContainer&) = default; 
    FooContainer(FooContainer&&) = default; 
    FooContainer& operator=(const FooContainer&) = default; 
    FooContainer& operator=(FooContainer&&) = default; 

    ~FooContainer() {} 
}; 

FooContainer getFooContainer() 
{ 
    FooContainer retval(0); 
    return retval; 
} 

int main() {}