2015-07-11 87 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(); 
}