2010-02-28 130 views
6

我想要一个模板类,看起来像我下面的东西。然后,我想根据CLASS模板参数使用模板专门化功能。我如何完成这项工作?我意识到我提供的代码在很多层面都是错误的,但它只是为了说明这个概念。模板类,功能专业

template <typename _T, size_t num> 
class Foo 
{ 
    // If num == 1, I want to call this function... 
    void Func<_T, 1>() 
    { 
     printf("Hi!"); 
    } 

    // Otherwise, I want to call this version. 
    void Func<_T, num>() 
    { 
     printf("Hello world!"); 
    } 
}; 

回答

9
struct Otherwise { }; 
template<size_t> struct C : Otherwise { }; 

// don't use _Uppercase - those names are reserved for the implementation 
// (i removed the '_' char) 
template <typename T, size_t num> 
class Foo 
{ 
public: 
    void Func() { Func(C<num>()); } 

private: 
    // If num == 1, I want to call this function... 
    void Func(C<1>) 
    { 
     printf("Hi 1!"); 
    } 

    // If num == 2, I want to call this function... 
    void Func(C<2>) 
    { 
     printf("Hi 2!"); 
    } 

    // Otherwise, I want to call this version. 
    void Func(Otherwise) 
    { 
     printf("Hello world!"); 
    } 

    //// alternative otherwise solution: 
    // template<size_t I> 
    // void Func(C<I>) { .. } 
}; 
+0

我喜欢这个解决方案。我甚至学到了关于C++命名约定的知识!然而,如果我有,例如,任何数量的专业化的数量的num和随后的情况下,他们都不工作,我该如何做到这一点? – 2010-02-28 04:24:13

+0

@wowus,已更新回答 – 2010-02-28 04:32:29

+0

谢谢,接受。 – 2010-02-28 04:40:59

2

有功能 模板没有偏特,以及部分专业需要先 部分专业类模板的成员。

template< typename _T, size_t num > 
struct Foo { 
    void Func() { 
     printf("Hello world!"); 
    } 
}; 

template< typename _T > 
struct Foo< _T, 1 > { 
    void Func() { 
     printf("Hi!"); 
    } 
}; 

现在,如果Foo还含有比Func其实现独立于num价值的其他方法,并且你不想重复他们实施的Foo专业化,你可以应用以下模式:

template< typename _T, size_t num > 
struct FooFuncBase { 
    void Func() { 
     printf("Hello world!"); 
    } 
}; 

template< typename _T > 
struct FooFuncBase< _T, 1 > { 
    void Func() { 
     printf("Hi!"); 
    } 
}; 

template< typename _T, size_t num > 
struct Foo : public FooFuncBase< _T, num > { 
    void OtherFuncWhoseImplementationDoesNotDependOnNum() { 
    ... 
    } 
}; 

或者,使用CRTP

template< typename _Derived, typename _T, size_t num > 
struct FooFuncBase { 
    void Func() { 
     static_cast< _Derived* >(this)->OtherFuncWhoseImplementationDoesNotDependOnNum(); 
     printf("Hello world!"); 
    } 
}; 

template< typename _Derived, typename _T > 
struct FooFuncBase< _Derived, _T, 1 > { 
    void Func() { 
     static_cast< _Derived* >(this)->OtherFuncWhoseImplementationDoesNotDependOnNum(); 
     printf("Hi!"); 
    } 
}; 

template< typename _T, size_t num > 
struct Foo : public FooFuncBase< Foo< _T, num >, _T, num > { 
    void OtherFuncWhoseImplementationDoesNotDependOnNum() { 
    printf("Other"); 
    } 
}; 
+0

它是被专门在这种情况下一个类中,OP只是不知道怎么写的,我觉得语法。 – 2010-02-28 03:54:01

+1

我想还有更多,让我们看看他的答案。我几乎可以肯定他只需要专门研究'Foo'方法的一个子集,而不是整个班级。 – vladr 2010-02-28 03:59:45

+0

我喜欢这个解决方案,但是我认为把“特殊情况代码”放在公共接口和所有普通代码中是相当危险的。当然有更好的办法! – 2010-02-28 04:04:01

1

这称为部分模板专业化。它看起来像这样:

template<typename _T, size_t num> 
class FooBase 
{ 
}; 

template <typename _T, size_t num> 
class Foo : public FooBase<_T,num> 
{ 
    void Func() 
    { 
     printf("Hello world!"); 
    } 
}; 


template <typename _T> 
class Foo<_T,1> : public FooBase<_T,num> 
{ 
    void Func() 
    { 
     printf("Hi!"); 
    } 
} 
+0

我不想在每个专业领域重复Foo的全部内容(还有其他许多我已经省略的方法)。 – 2010-02-28 03:54:30

+0

被编辑为允许在基类中的函数。 – 2010-02-28 05:52:29