2013-04-06 62 views
0

我遇到某種模板重定義錯誤。這不是一個解決方案突破錯誤(我找到了解決方法),但我仍然想知道爲什麼代碼是錯誤的。使用VS 2010編譯時模板重定義錯誤

template <typename RandomEngine, typename RandomDistribution = std::uniform_int_distribution<int> > 
struct base_random_generator { 
    RandomEngine generator; 
    RandomDistribution distribution; 
    base_random_generator(RandomEngine gen, 
          RandomDistribution dist = RandomDistribution(0, 10)) 
     : generator(gen), distribution(dist) { } 
    int operator()() { 
     return distribution(generator); 
    } 
}; 

base_random_generator<std::mt19937> 
create_mt_generator(std::mt19937::result_type seed = std::mt19937::default_seed) { 
    return base_random_generator<std::mt19937> (std::mt19937(seed)); 
} 

Visual Studio 2010中失敗,此錯誤編譯上面的代碼:

... already defined in main.obj

fatal error LNK1169: one or more multiply defined symbols found

如果我刪除create_mt_generator功能,然而,錯誤消失,所有又是很好的。 我的主要想法是能夠傳遞一個類似於std :: function的結構,所以我可以一遍又一遍地調用它來獲得一個隨機整數。

爲了這個功能看起來是這樣的:

template <typename Container, typename RandomGenerator> 
void scramble(Container c, RandomGenerator rand) { } 

我認爲這將是需要能夠動態創建一個隨機數生成器類與用戶給出的參數。

+0

您的'create_mt_generator'函數返回一個模板對象,但它不是*模板函數,因此需要頭文件之外的主頁。如果你想把它保存在標題中,你可以聲明它是'inline'(或'static')。 – WhozCraig 2013-04-06 04:47:14

回答

1

只有某些類型的功能應該在頭文件中定義:

  • inline
  • template
  • static

在其他情況下,將定義在短短的一個編譯單元,並在頭文件中使用前向聲明(原型)以使其他編譯單元可見。