2011-10-28 34 views
1

我們在使用其中一些成員函數中使用函數對象的類模板時遇到問題。該錯誤消息形成VS2010編譯器:在使用模板時缺少默認構造函數

錯誤C2512: 'SimpleFunctor :: SimpleFunctor':可用

小型化的代碼來重現此如下:沒有適當的默認構造函數 :

// myfunctor.h

class SimpleFunctor 
{ 
    private: 
    SimpleFunctor(const SimpleFunctor&); 
    SimpleFunctor& operator=(const SimpleFunctor&); 
    public: 
    bool operator()() { return true; } 
}; 

// mytemplate.h

#include "myfunctor.h" 

template< typename T > 
class Test 
{ 
    private: 
    Test(const Test&); 
    Test& operator=(const Test&); 
    public: 
    Test(){} 

    void testFunction(T parameter) 
    { 
     bool result = SimpleFunctor()(); 
    } 
}; 

// main.cpp中

#include "HK_Template.h" 

int main() 
{ 
    Test<int> obj; 
    obj.testFunction(5); 

    return 0; 
} 

此示例產生這似乎是正確的,因爲添加默認的構造類似SimpleFunctor上述錯誤消息:

SimpleFunctor() {} 

修復了錯誤。

所以問題是,爲什麼編譯器不生成默認的構造函數?

+0

+1對於一個非常好的問題 –

回答

5

一旦自己定義了任何構造函數,包括複製構造函數,編譯器就不會再生成默認構造函數。

(在另一方面,複製/移動構造是默認生成如果你不提供,但需遵守一定的規則。)

+0

唉,我正要做出同樣的答案! '+ 1'。 – sbi

+0

確切地說,只是爲了清楚起見,這種行爲與模板無關,它是一個通用的C++規則 –

0

當你穿上編譯器只提供了一個默認的構造函數」 t定義 任何構造函數。由於您聲明瞭用戶定義的副本 構造函數,編譯器將不會提供它。

看起來你聲明拷貝構造函數的唯一原因是 使它變爲私有的,因此禁用它。在這種情況下,更好的 解決方案可能是從boost::noncopyable繼承的,它具有 相同的效果,但不妨礙編譯器生成默認構造函數 。

+0

或者[顯式刪除](http://en.wikipedia.org/wiki/C%2B%2B11# Explicitly_defaulted_and_deleted_special_member_functions)複製構造函數。 –

+0

@Als這隻有在你的編譯器支持C++ 11時纔可能。對於大多數開發人員來說這不是一個選項 –