在C++ 14应用程序的上下文中,我使用了一个可以恢复如下的方案(最小可重复性测试):
templatestruct LocateFunctions { auto get_it() const // <-- here is the problem { auto ret = typename Container::Iterator(); return ret; } }; template struct A : public LocateFunctions> { struct Iterator {}; }; int main() { A a; }
这种方法在C++ 14中使用GCC和Clang编译器进行编译和运行.
现在我想将我的应用程序迁移到Windows,为此我正在使用MinGW.不幸的是,它的最新版本带来了GCC 4.9,它不能编译C++ 14.这似乎不是一个严重的问题,因为我可以在C++ 11中重写C++ 14结构.所以,我重写get_it()
方法如下:
typename Container::Iterator get_it() const { auto ret = typename Container::Iterator(); return ret; }
不幸的是它没有编译.两个编译器都会产生以下错误:
error: no type named ‘Iterator’ in ‘struct A’ typename Container::Iterator get_it() const ^
我也尝试过:
auto get_it() const -> decltype(typename Container::Iterator()) { auto ret = typename Container::Iterator(); return ret; }
但我得到完全相同的错误.
由于两个编译器无法识别返回类型,我认为无法确定它.但我真的不知道为什么.
有人可以解释一下为什么不编译并最终在C++ 11中编译重构的方法?
你正在使用CRTP; LocateFunctions
使用A
(A
)的不完全特化实例化,因此访问该特化的成员会给出相当误导性的错误消息("不...命名...在...中"而不是"......不完整").但是,在您的示例中,函数temploid get_it
仅在(如果有)实例化之后A
确实定义,使得typename-specifier格式良好.
至于解决方法,尝试实现类似的效果,例如通过
templatetypename T::Iterator get_it() const { static_assert(std::is_same {}, "You ain't supposed to supply T!"); auto ret = typename T::Iterator(); return ret; }
GCC 4.9演示.