c++ - 不能使用一个类的成员 typedef 作为模板特化定义中的模板参数

标签 c++ templates c++11 template-specialization

抱歉标题又长又模糊。

我一直在努力实践我从《现代C++设计》一书中学到的东西。作为这项事件的一部分,我既尝试实现书中所述的命令模式,又尝试将其迁移到 C++11。

我现在处于这种状态:Coliru

我实现了 TypeListGenerator<...>替换 TYPELIST_N(...)能够使用可变参数模板:

// without variadic templates
#define TYPELIST_0() NullType
#define TYPELIST_1(T1) TypeList<T1, NullType>
#define TYPELIST_2(T1, T2) TypeList<T1, TYPELIST_1(T2)>
...

// with variadic templates
template <typename Head, typename... Rest> struct TypeListGenerator {
    using result = TypeList<Head, typename TypeListGenerator<Rest...>::result>;
};
template <> struct TypeListGenerator<NullType> {
    using result = NullType;
};
template <typename Last> struct TypeListGenerator<Last> {
    using result = TypeList<Last, NullType>;
};

现在问题在下面的代码中:

template <typename R, typename P1>
//class FunctorImpl<R, typename TypeListGenerator<P1>::result> { // <-- #1 - Does not compile
class FunctorImpl<R, TYPELIST_1(P1)> { //<-- #2 - Compiles
    public:
    virtual R operator()(P1) = 0;
    virtual FunctorImpl* clone() const = 0;
    virtual ~FunctorImpl() = 0;
};

template <typename R, typename TL>
class Functor {
    using P1 = typename TypeAtNonStrict<TL, 0, EmptyType>::type;
    using P2 = typename TypeAtNonStrict<TL, 1, EmptyType>::type;
    using P3 = typename TypeAtNonStrict<TL, 2, EmptyType>::type;
    using P4 = typename TypeAtNonStrict<TL, 3, EmptyType>::type;
public:
    Functor() : impl_(nullptr) { }
    R operator()() { return (*impl_)(); }
    R operator()(P1 p1) { return (*impl_)(p1); }
    R operator()(P1 p1, P2 p2) { return (*impl_)(p1, p2); }
    R operator()(P1 p1, P2 p2, P3 p3) { return (*impl_)(p1, p2, p3); }
private:
    FunctorImpl<R, TL>* impl_;
};

int main() {
    Functor<double, typename TypeListGenerator<int>::result> f1;
    double r1 = f1(1);
}

如果我取消注释 #1,它会编译。但是如果我取消注释#2,它不会并给出以下错误:

main.cpp:148:7: error: template parameters not used in partial specialization:
 class FunctorImpl<R, typename TypeListGenerator<P1>::result> {
       ^
main.cpp:148:7: error:         'P1'

注意:我只展示了代码的重要部分,完整代码在Coliru

最佳答案

这是非推导上下文的情况。下面给出了非推导上下文的非正式解释,更多信息可以通过谷歌搜索找到。

简单来说,给定XX<Y>::Z , 你不能推断出 Y .

假设 TypeListGenerator<Foo>::resultint , 和 TypeListGenerator<Bar>::result也是int .

你通过了int到您的模板,它是否有机会了解它实际上是 TypeListGenerator<Foo>::result而不是 TypeListGenerator<Bar>::result ?不。

但我仔细定义了我的TypeListGenerator<Foo>::result以一种独特的方式,实际上可以恢复 P1 , 你说。没关系。一般情况下不存在恢复它的过程,所以语言规则说它没有完成。

关于c++ - 不能使用一个类的成员 typedef 作为模板特化定义中的模板参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23843768/

相关文章:

c++11 注册缓存线程安全

c++ - wxTextEntryDialog 翻译确定和取消

c++ - LLVM:生成运行时错误

c++ - Wordcount C++ Hadoop 管道不起作用

c++ - 是否可以模板化 basic_string<>::iterator?

c++ - std::vectors 中 size_type 的更短符号

c# - Winpcap 简单问题——如何向指定的ip/端口发送数据包?

javascript - 将属性应用于 Angular Directive(指令)中的自定义嵌套元素

javascript - 在模板内渲染剑道网格导致错误

c++ - 返回指向 const 数据成员的 const 指针和 'auto' 关键字。有点迷茫