嵌套在模板化类中的类型的部分特化

neo*_*phi 6 c++ templates specialization

我正在玩模板和部分专业化,但有一个专业化,我不知道如何写...我将简化代码,使其更容易阅读.

让我们了

template <typename T>
    class x
{
    ...
};
Run Code Online (Sandbox Code Playgroud)

通常,我可以像这样专注:

class x<a_type>
{
    ...
};
Run Code Online (Sandbox Code Playgroud)

也适用于模板类型:

template <typename T>
    class x<std::vector<T>>
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

现在我想对嵌套在模板化类中的类型进行专门化:

template <typename T>
    class y
{
    struct nested_type
    {
        y a_member;
    };

    ...
};

// Here comes the specialization

template <typename T>
    class x<y<T>::nested_type>
{
    ...
};
Run Code Online (Sandbox Code Playgroud)

这失败了.我还尝试在y :: nested_type之前放置'typename',但它没有解决问题.编译器错误是:

type/value mismatch at argument 1 in template parameter list for ‘template <class T> struct x’
Run Code Online (Sandbox Code Playgroud)

我想做的事似乎合乎逻辑,但我不确定它是否可行.我正在使用带有g ++ - 4.5的C++ 0x.有没有人知道写这种专业化的正确语法?

Mik*_*son 5

答案是你不能做这个专业化.它不是语法错误,而只是无法实现的东西.你必须看到模板特化有点像函数重载.编译器必须在use-site处获取type参数,查看可用的特化,查找匹配,并选择最佳的(最专业的).您的示例的问题在于,使用这样的专业化无法实现"查找匹配"步骤.编译器可以期望"nested_type"是任何东西,不一定是唯一类型(就像在你的例子中一样),例如它也可以是嵌套的typedef.此外,编译器无法预测它已经看到模板"y"的所有特化,所以即使nested_type是嵌套在y(通用模板)中的唯一类型,它也可能是即将发布的模板模板特化声明中的嵌套typedef "Y".

就像函数重载和在那里使用的匹配算法一样,编译器在推断类型方面的能力有限,它限制了它可以做出多少假设.如果你有专业化x<int>和以后使用x<int>,匹配是微不足道的,不需要扣除,不需要任何假设.如果你有专业化x<T*>和以后使用x<int*>,匹配很容易,T可以推断为int.如果你有一个专业化x< y<T>::type >,然后使用任何版本的x,编译器应该如何从y :: type中推导出T?它必须替换整个世界中存在的所有可能类型中的T,以查看是否存在导致匹配嵌套类型的类型.这是一个不合理的期望,这就是为什么C++模板的类型推导功能在此停止.通常,要知道您是否应该期望编译器能够解决某些问题,只需将自己放在一边,看看它是否可以远程实现(答案通常很清楚).