c++ - 内部类取决于模板参数

标签 c++ templates metaprogramming partial-specialization pimpl-idiom

考虑下一个例子:

#include <iostream>
#include <typeinfo>

template< int N, typename T >
struct B
{
    struct C;
};

template< typename T >
struct B< 0, T >::C
{
    typedef T type;
};

template< int N, typename T >
struct B< N, T >::C
{
    typedef T type[N];
};

int main()
{
    std::cout<<"n=0   type = " << typeid( B< 0, float >::C::type ).name() << std::endl;
    std::cout<<"n=5   type = " << typeid( B< 5, float >::C::type ).name() << std::endl;
}

使用 g++(版本 4.3.0)编译时

g++ dfg.cpp  -ansi -pedantic -Wall

编译错误是:

dfg.cpp:13: error: qualified name does not name a class before ‘{’ token
dfg.cpp: In instantiation of ‘B<0, float>::C’:
dfg.cpp:25:   instantiated from here
dfg.cpp:20: error: ISO C++ forbids zero-size array

我真正想要归档的是根据枚举值拥有不同的 Imp 实现(在示例中,我使用 int 而不是枚举,但这应该不重要)。

有人可以解释为什么这是不允许的吗? 为什么我会收到第一个错误? (这个:限定名称不在“{”标记之前命名类)


关于依赖于模板参数的 pimpl 实现,我创建了一个新问题(有更好的示例)here

最佳答案

这无效:

template< typename T >
struct B< 0, T >::C
{
    typedef T type;
};

可以专门化类模板的成员,但仅限于这些类模板的隐式实例化。用简单的英语来说,这意味着:仅当您为封闭类模板(您需要专门化其成员)的所有模板参数提供值时。

template< >
struct B< 0, int >::C
{
    typedef T type;
};

你写的是B<0, T>::C的定义,它是 B<N, T> 的类模板部分特化的成员。这种部分特化并不存在,因此编译器会出错。


您有多种选择来解决此问题。一是

template< int N, typename T >
struct B
{
    template<typename N1, typename T1>
    struct CMember { typedef T1 type[N1]; };

    template<typename T1>
    struct CMember<0, T1> { typedef T1 type; };

    struct C { 
      typedef typename CMember<N, T>::type type;
    };
};

请注意,显式特化(非部分)不能直接放入类模板中(因此, template<> struct CMember<0, int> { ... }B 的主体内写入时格式不正确)。您需要在 B 之外定义“选择器”模板然后(可能在 detail 命名空间中)。

其他替代方案包括源自 CMember并继承它的 typedef。

关于c++ - 内部类取决于模板参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5419670/

相关文章:

Ruby - 使用实例变量的 DSL

Ruby eigenclass(单例类)创建了吗?为了哪个?

ruby - 找到模块子项的更好方法?

c++ - 使用 union 的简单结构中的成员变量别名

c++ - 将 STL 数据结构传递给 opencl 内核

c++ - Visual Studios 2010 中的 libx264 - Release Build 中的内存错误

c++ - 将模板类声明为友元

C++构造函数、析构函数、类型转换错误

templates - 动态 Mandrill 模板是否支持对集合进行迭代?

Django StreamingHttpResponse 到模板中