2013-02-26 105 views
1

我有一個模板化的C++類與其成員函數之一的進一步模板。錯誤的編譯錯誤調用模板類的模板成員函數

我在我的代碼兩個地調用它,其中的一個作品,另生成歸結爲下面的示例代碼一個非常令人困惑的錯誤:

#include <memory> 

template <unsigned char N> 
struct Foo 
{ 
    template <typename OtherFoo, unsigned X> 
    void do_work (
     const OtherFoo * __restrict, 
     float, 
     Foo * __restrict 
     ) 
    const 
    { 
    } 
}; 

struct Bar 
{ 
    std :: unique_ptr <Foo<0>> foo_0; 
    std :: unique_ptr <Foo<1>> foo_1; 
    std :: unique_ptr <Foo<2>> foo_2; 

    void run (float); 

    template <typename FOO> 
    void run (std :: unique_ptr <FOO> & foo, float x) 
    { 
     FOO out; 
     foo -> template do_work <123> (foo_2.get(), x, &out); 
    } 
}; 

void Bar :: run (float x) 
{ 
    if (foo_0) 
     run (foo_0, x); 
    else 
     run (foo_1, x); 
} 

int main() 
{ 
    Bar bar; 
    bar .run (1.23); 
} 

錯誤消息是相當簡單的,但顯然是錯誤的。

temp.cpp: In member function ‘void Bar::run(std::unique_ptr<FOO>&, float) [with FOO = Foo<0u>]’: 
temp.cpp:61:16: instantiated from here 
temp.cpp:54:3: error: no matching function for call to ‘Foo<0u>::do_work(Foo<2u>*, float&, Foo<0u>*)’ 
temp.cpp: In member function ‘void Bar::run(std::unique_ptr<FOO>&, float) [with FOO = Foo<1u>]’: 
temp.cpp:63:16: instantiated from here 
temp.cpp:54:3: error: no matching function for call to ‘Foo<1u>::do_work(Foo<2u>*, float&, Foo<1u>*)’ 

讓我們來看看,對於呼叫沒有匹配功能Foo<1u>::do_work(Foo<2u>*, float&, Foo<1u>*) ...?不,對我而言,確切地說是就像一個有效的Foo :: do_work實例。

編譯器是否錯誤? (ubuntu 12.04上的gcc 4.5.1)特別奇怪的是,這段代碼確實在代碼中的其他地方進行了等價的調用(完整的東西有相當多的依賴被有意義地轉載)。

+0

嘗試GCC 4.7,它爲您提供了更詳細的錯誤消息。 – PlasmaHH 2013-02-26 15:19:35

回答

2

你應該改變你的模板參數的順序爲do_work<>()函數模板,或者您的實例確實將是不正確的:

// template<typename OtherFoo, unsigned X> // This order is not appropriate. 
              // Let template parameters that 
              // cannot be deduced come first... 
    template<unsigned X, typename OtherFoo> 
    //  ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^ 
    //  THIS FIRST  THEN THIS 
    void do_work(const OtherFoo* __restrict, float, Foo* __restrict) const 
    { 
    } 

這是因爲在下面的函數調用您提供了一個明確的說法第一模板參數:

foo->template do_work<123>(foo_2.get(), x, &out); 
+0

'__restrict'不是一個標識符,它是一個類型限定符。 – Xymostech 2013-02-26 15:22:47

+0

@Xymostech:哦,對不起。我應該知道了。修正了,謝謝。 – 2013-02-26 15:23:33