c++ - 这种语法合法吗?

标签 c++ templates c++11 inheritance variadic

当我取消注释下面 main() 中的行时,Visual Studio 2015 将无法编译(否则代码会编译)。

#include <iostream>
#include <type_traits>

template <typename Output, std::size_t... Input> struct RemoveLastHelper;

template <template <std::size_t...> class Z, std::size_t... Accumulated, std::size_t First, std::size_t... Rest>
struct RemoveLastHelper<Z<Accumulated...>, First, Rest...> :
    RemoveLastHelper<Z<Accumulated..., First>, Rest...> {};

template <template <std::size_t...> class Z, std::size_t... Accumulated, std::size_t Last>
struct RemoveLastHelper<Z<Accumulated...>, Last> {
    using type = Z<Accumulated...>;
};

template <template <std::size_t...> class Z, std::size_t... Is>
using RemoveLast = RemoveLastHelper<Z<>, Is...>;

struct Base {
    virtual ~Base() = default;
    virtual void foo() const = 0;
};

template <std::size_t... Is> struct Derived;

template <std::size_t R>
struct Derived<R> : public Base {
    virtual void foo() const override {}
};

// For example, Derived<R,D1,D2,D3> inherits from Derived<R,D1,D2>, which inherits from
// Derived<R,D1>, which inherits from Derived<R>, which inherits from Base (by the above).
template <std::size_t R, std::size_t... Is>
struct Derived<R, Is...> : public RemoveLast<Derived, R, Is...>::type {
    virtual void foo() const override {RemoveLast<Derived, R, Is...>::type::foo();}
};

int main() {
//  Derived<0,2,1> r;  // This line won't compile.
}

它给出了错误:

'Derived<0,2>': invalid template argument for template parameter 'Z', expected a class template
'RemoveLast': left of '::' must be a class/struct/union
'type': is not a class or namespace name

那么这里有什么问题呢? GCC 5.1 编译它,但我想知道这是否只是侥幸。语法是virtual void foo() const override {RemoveLast<Derived, R, Is...>::type::foo();}合法的?如果没有,我如何实现它(我只希望它调用其基类的 foo())。如果它是合法的,我该如何重写它以便 Visual Studio 接受它(我需要它在 Visual Studio 上工作)?

最佳答案

这是一个简单的修复。将 Derived 替换为 Derived::template Derived

template <std::size_t R, std::size_t... Is>
struct Derived<R, Is...> : public RemoveLast<Derived, R, Is...>::type {
    virtual void foo() const override {RemoveLast<Derived::template Derived, R, Is...>::type::foo();}
};

::Derived 也可以。这似乎是 Clang 和 Visual Studio 中都存在的关于注入(inject)类名的错误。

关于c++ - 这种语法合法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32064209/

相关文章:

c++ - 将一个函数模板的模板参数映射到另一个函数模板的模板参数 (c++)

c++ - gdb (armv7) 中的无效转换

c++ - 使用定义相互依赖

c++ - strspn C++ 下的奇怪行为,为什么?

c++ - 字符串比较运算符的含义是什么?

c++ - 强制转换为 C++ 中的字符串运算符重载

c++ - 何时重载按引用传递(左值和右值)优于按值传递?

c++ - 模板 typedef c++0x

c++ - 模板运算符的不明确重载

c++ - C++ 是否支持归纳类型定义?