c++ - Is this a bug in GCC? -
edit: not bug, me not knowing dependent name lookups in templated base classes (which msvc "helpfully" resolves without errors).
i wrote functor implementation while back, , simple "event" wrapper uses it. compiles fine under msvc, gcc gives error member variable in base class, subscribers
, not being declared; changing subscribers
this->subscribers
resolves issue(!). appears happen curiously recurring template pattern, , partial template specialization.
simplified source (sorry mind-bending template usage...):
#include <vector> template<typename tevent> struct eventbase { protected: std::vector<int> subscribers; }; template<typename targ1 = void, typename targ2 = void> struct event : public eventbase<event<targ1, targ2> > { void trigger(targ1 arg1, targ2 arg2) const { // error on next line auto = subscribers.cbegin(); } }; template<typename targ1> struct event<targ1, void> : public eventbase<event<targ1> > { void trigger(targ1 arg1) const { // using `this` fixes error(?!) auto = this->subscribers.cbegin(); } }; template<> struct event<void, void> : public eventbase<event<> > { void trigger() const { // no error here without `this`, reason! auto = subscribers.cbegin(); } }; int main() { return 0; }
am invoking undefined behaviour somewhere? syntax somehow wrong? bug in gcc? perhaps known bug? insight appreciated!
more details: compiled using g++ -std=c++11 main.cpp
. i'm using gcc version 4.7.2. exact error message:
main.cpp: in member function ‘void event<targ1, targ2>::trigger(targ1, targ2) const’: main.cpp:17:15: error: ‘subscribers’ not declared in scope
this bug in msvc instead. names dependent base classes have "thisambiguated".
the reason unqualified lookup of dependent names proceeds in 2 phases. during first phase, base class not yet known , compiler cannot resolve name. msvc not implement two-phase name lookup , delays lookup until second phase.
the full specialization
template<> struct event<void, void> : public eventbase<event<> > { void trigger() const { // no error here without `this`, reason! auto = subscribers.cbegin(); } };
does not suffer problem, because both class , base regular classes, not class templates, , there no template dependency begin with.
when porting c++ code msvc gcc/clang, dependent name lookup disambiguation , template
keyword disambiguation (i.e. calling member function template using ::template
, ->template
or .template
syntax) 2 of subtleties have deal (empty base optimization one). standards compliance rhetoric, never fixed reasons of backwards compatibility.
Comments
Post a Comment