很抱歉,标题冗长而含糊。
我一直在尝试练习从《现代C++设计》一书中学到的知识。作为此 Activity 的一部分,我既试图按照书中所述实现命令模式,又试图将其迁移到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中
最佳答案
这是非推论上下文的情况。下面给出了非推论上下文的非正式解释,可以通过Google搜索找到更多信息。
简而言之,给定X
和X<Y>::Z
,就无法推断Y
。
假设TypeListGenerator<Foo>::result
是int
,并且TypeListGenerator<Bar>::result
也是int
。
您将int
传递给模板,是否有机会了解它实际上是TypeListGenerator<Foo>::result
而不是TypeListGenerator<Bar>::result
?不。
但是,我说,我以独特的方式仔细定义了自己的TypeListGenerator<Foo>::result
,以便实际上可以恢复P1
。没关系通常情况下,不存在恢复它的过程,因此语言规则说它没有完成。
关于c++ - 不能在模板专门化定义中将一个类的成员typedef用作模板参数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23843768/