2015-07-11 128 views
2

是否可以在聲明外移動方法定義?模板嵌套類在聲明外移動方法定義

template <typename T1> 
class A 
{ 
    template <bool T2> 
    class B; 

    template<> 
    class B<true> 
    { 
    void f() { /* Do smg */ } 
    } 
    class B<false> 
    { 
    void f() { /* Do smg else */ } 
    } 
} 

如果我嘗試將f()類的聲明之外,這樣

template <typename T1> 
template <> 
void A<T1>::B<true>::f() { /* Do smg */ } 

編譯器會發出錯誤C3855:模板參數T2與聲明不符。

+0

海合會4.7.2,我不能讓你頂塊編譯由於''錯誤:明確的專業化非命名空間範圍「A級」''。它應該是一個有用的例子嗎?我明白從這個問題... –

+0

VS2013編譯頂部塊沒有錯誤。 – Vladislav

+0

不是VS方面的專家,但它被認爲是一個編譯器,並沒有那麼好的合規性。我的猜測是這兩個街區在技術上都是非法的。 g ++的錯誤對我有意義。無論如何,我在你的問題中添加一個VS標籤。 –

回答

1

不能明確專業非專業類模板的類成員模板,從[temp.expl.spec]:

In an explicit specialization declaration for a member of a class template or a member template that appears in namespace scope, the member template and some of its enclosing class templates may remain unspecialized, except that the declaration shall not explicitly specialize a class member template if its enclosing class templates are not explicitly specialized as well.

BA的定義內甚至明確specialiation是病態的。如果你需要做這樣的事情,我不會使用B的成員類模板。

0

我發現了一種破解系統的方法。使用偏特,而不是明確的分工,有假的模板參數,就像這樣:http://goo.gl/yHRQwV

template <typename T1> 
class A 
{ 
public: 
    template <bool T2, typename = void> 
    class B; 

    template <typename Dummy> 
    class B<true, Dummy> 
    { 
    public: 
    void f1(); 
    }; 

    template <typename Dummy> 
    class B<false, Dummy> 
    { 
    public: 
    void f1(); 
    }; 
}; 

template <typename T1> 
template <typename Dummy> 
void A<T1>::B<true, Dummy>::f1() 
{ 
} 

template <typename T1> 
template <typename Dummy> 
void A<T1>::B<false, Dummy>::f1() 
{ 
} 

int main() 
{ 
    A<int>::B<true> b1; 
    b1.f1(); 

    A<int>::B<false> b2; 
    b2.f1(); 
} 

不知道這是合法的,但它的工作原理。

實際上,它並沒有解決我的問題。在這種情況下,我不能添加的一般方法F2(),F3()等,B類無專業化:http://goo.gl/wtIY0e

template <typename T1> 
class A 
{ 
public: 
    template <bool T2, typename = void> 
    class B 
    { 
    public: 
    void f2(); 
    void f3(); 
    }; 

    template <typename Dummy> 
    class B<true, Dummy> 
    { 
    public: 
    void f1(); 
    }; 

    template <typename Dummy> 
    class B<false, Dummy> 
    { 
    public: 
    void f1(); 
    }; 
}; 

template <typename T1> 
template <typename Dummy> 
void A<T1>::B<true, Dummy>::f1() 
{ 
} 

template <typename T1> 
template <typename Dummy> 
void A<T1>::B<false, Dummy>::f1() 
{ 
} 

template <typename T1> 
template <bool T2, typename Dummy> 
void A<T1>::B<T2, Dummy>::f2() 
{ 
} 

template <typename T1> 
template <bool T2, typename Dummy> 
void A<T1>::B<T2, Dummy>::f3() 
{ 
} 

int main() 
{ 
    A<int>::B<true> b1; 
    b1.f1(); 
    b1.f2(); // error: A<int>::B<true> has no member f2 
    b1.f3(); // error: A<int>::B<true> has no member f3 
    A<int>::B<false> b2; 
    b2.f1(); 
    b2.f2(); // error: A<int>::B<false> has no member f2 
    b2.f3(); // error: A<int>::B<false> has no member f3 
} 

最後,我發現,在尋找了整整一天的解決方案:靜態多態性http://goo.gl/7yGZxM

template <typename T1> 
struct A 
{ 
    template<typename T2> 
    struct BaseB 
    { 
    void f1(); 
    void f2(); 
    void f3(); 
    }; 

    struct B_true : BaseB<B_true> 
    { 
    void f1_impl(); 
    }; 

    struct B_false : BaseB<B_false> 
    { 
    void f1_impl(); 
    }; 
}; 

template <typename T1> 
template<typename T2> 
void A<T1>::BaseB<T2>::f1() 
{ 
    static_cast<T2*>(this)->f1_impl(); 
} 

template <typename T1> 
template<typename T2> 
void A<T1>::BaseB<T2>::f2() 
{ 

} 

template <typename T1> 
template<typename T2> 
void A<T1>::BaseB<T2>::f3() 
{ 

} 

template <typename T1> 
void A<T1>::B_true::f1_impl() 
{ 

} 

template <typename T1> 
void A<T1>::B_false::f1_impl() 
{ 

} 

int main() 
{ 
    A<char>::B_true b_true; 
    b_true.f1(); 
    b_true.f2(); 
    b_true.f3(); 

    A<char>::B_false b_false; 
    b_false.f1(); 
    b_false.f2(); 
    b_false.f3(); 
}