【发布时间】:2014-02-10 06:49:32
【问题描述】:
在这个例子中:
template<typename T>
struct ConditionalValue
{
typedef boost::optional<T> type;
};
template<typename T>
struct FindRootValueType
{
typedef typename T::root_type type;
};
template<typename T>
struct FindRootValueType<typename ConditionalValue<T>::type>
{
typedef typename ConditionalValue<T>::type type;
};
template<typename T>
struct Base
{
typedef T value_type;
typedef typename FindRootValueType<value_type>::type root_type;
std::vector<value_type> data;
};
template<typename T>
struct A : public Base<typename ConditionalValue<T>::type>
{
};
template<typename T>
struct B : public Base<A<T>>
{
};
template<typename T>
struct C : public Base<B<T>>
{
};
// C<int>::value_type == B<int>
// C<int>::data == std::vector<B<int>>
// C<int>::data ~= std::vector<std::vector<std::vector<boost::optional<int>>>>
// C<int>::root_type == boost::optional<int>
ConditionalValue 是一个模板别名,它只是尝试为boost::optional 提供一个替代名称(这样可以使用其他东西来替换它),FindRootValueType 是一个元函数,旨在遍历一系列类型其定义类似于底部显示的定义,直到它停在boost::optional,然后简单地返回。
但是,正如所写的那样,这不起作用(至少在 VS2008 中不起作用)。要修复它,FindRootValueType 的特化必须显式使用boost::optional<T>,而不是应该与其等效的 typedef。 (这违背了仅在一个地方指定底层实现类型的目标。)
这是编译器错误还是应该不起作用?还是我只是做错了什么?有没有更好的方法来编写它以使其按预期工作?
我也尝试过这样颠倒逻辑:
template<typename T>
struct FindRootValueType
{
typedef T type;
};
// define Base here
template<typename T>
struct FindRootValueType<Base<T>>
{
typedef typename T::root_type type;
};
// define A here
template<typename T>
struct FindRootValueType<A<T>>
{
typedef T type;
};
// define B, C here (no specialisation)
但这也不起作用(我认为是因为专业化不遵循基本类型,或者可能只是定义的顺序)。我不想专门针对 B、C 等。
(顺便说一句,在上述两种情况下,“不工作”意味着产生了编译器错误,表明它使用的是FindRootValueType 的基本定义,而不是专门化。)
【问题讨论】:
标签: c++ templates metaprogramming template-specialization