使用typename使用模板转发类声明

时间:2014-01-10 15:36:27

标签: c++ c++11

我有以下情况: -

template<typename Derived, typename ValType>
class foo
{
public:
    template<typename R>
    bar<typename std::vector<R>::const_iterator> select()
    {
        std::vector<R> translation;

        return bar<typename std::vector<R>::const_iterator>(std::move(translation));
    }
};

template<typename T>
class bar
    : public foo<bar<T>, typename std::iterator_traits<T>::value_type>
{
public:
    bar(std::vector<typename std::iterator_traits<T>::value_type>&& vec)
    {

    }
};

这基本上是一个小概念证明我正在使用CRTP,foo是mixin。

问题在于我相信我应该使用前瞻性声明,但我尝试过以下方法: -

class bar; // I didn't expect this to work

但我确实希望这可行: -

template<typename R>
class bar;

编译好,直到我实际调用select()

std::vector<int> enumerable_vector;
enumerable_vector.push_back(1);
enumerable_vector.push_back(2);

bar<typename std::vector<int>::const_iterator> baz(std::move(enumerable_vector));
baz.select<std::string>();

会导致以下错误: -

  

错误错误C2027:使用未定义类型   '富:: bar' 的

任何帮助都会很感激,谢谢!

2 个答案:

答案 0 :(得分:3)

  

错误错误C2027:使用未定义类型'foo :: bar'

错误消息似乎表明您在bar内转发了声明的嵌套类型foo。您需要转发声明正确的类型(将bar的声明移到foo的定义上的命名空间级别

答案 1 :(得分:0)

编辑:这个答案是不正确的。当bar 定义时,select无需完成,select 实例化时必须完整。在select的类说明符之后移动bar的定义不是必需的。


问题是您在select的类说明符中定义foo需要bar完成。如果您在类说明符中转发声明bar并且仅声明 select,则可以将select的定义移到行外{{1} }} 完成了。 It then compiles fine

bar
相关问题