这种语法合法吗?
Is this syntax legal?
本文关键字:语法 更新时间:2023-10-16
当我取消下面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中存在的一个关于注入类名的错误。
相关文章:
- 1d 智能指针不适用于语法 (*)++
- 助记符和指向成员语法的指针
- 有人能分解一下这个c++模板的语法吗
- C++避免重复声明的语法是什么
- QMetaObject invokeMethod的基于函数指针的语法
- 这个语法std::class<>{}(arg1, arg2) 在C++中是什么意思?
- 为什么包含windows.h会产生语法错误,从而阻止类的实例化?(C2146,C2065)
- 单独定义模板化嵌套类方法的正确语法
- 共享指针和具有自定义删除程序的唯一指针之间的语法差异背后的任何原因
- 错误 C2760:语法错误:映射迭代器上意外的标记"标识符",预期的";"
- 为什么我会收到错误 C2143 语法错误:缺少"*"之前的';'?
- 奇怪的代码抛出编译错误模板< J,int aSize=10> C2143:语法错误:在"<"之前缺少";"
- 使用基类指针调用基类的值构造函数的语法是什么?
- 很好的语法来获取对向量/数组数据的大小引用?
- C++语法运算符功能?
- C++使用 rand 定义函数语法
- 什么文件可以修改 atom 的C++语法?
- 创建模板嵌套类实例的语法?
- C++语法差异:二维和一维数组(指针算术)
- 将信息输入到下面显示的结构向量中的正确语法/格式是什么