使用 g++ 4.6 和 4.8 编译此代码时出现错误。g++ 4.2 和 4.4 都可以。这是一个错误还是一些新的语言功能?
template <typename T>
struct A { typedef typename T::value_type type; };
template <typename U>
struct B
{
void bar () { }
void foo ()
{
// OK
this->bar ();
// OK
(*this).bar ();
// Error in g++ 4.6-4.8
// leads to full instantiating of template arg "U"
(&*this)->bar ();
}
};
int main ()
{
B< A<void> > b;
b.foo ();
return 0;
}
g++ inst.cc
inst.cc: In instantiation of ‘struct A<void>’:
inst.cc:20:5: required from ‘void B<U>::foo() [with U = A<void>]’
inst.cc:27:10: required from here
inst.cc:3:34: error: ‘void’ is not a class, struct, or union type
typedef typename T::value_type type;
^
更新 1:我知道 A 不能被实例化。
问题是:为什么编译器试图在“(&*this)->bar ()”行而不是在“this->bar ()”或“(*this).bar ()”行实例化它?
更新 2:
建议的解决方法addressof (object)
对我不起作用,因为实际上我在尝试使用std::bind (&B::bar, this)
. 真正的代码当然要复杂得多,并且bind
没有单独使用,但问题是追溯到简单的std::bind
表达式。
我不想重写或重新发明std::bind
,所以我不得不使用CRTP让它工作:
#include <tr1/functional>
template <typename T>
struct A { typedef typename T::value_type type; };
template <typename Derived, typename U>
struct B
{
Derived* derived (void) { return static_cast<Derived*>(this); }
void bar () { }
void foo ()
{
// error with recent compiler.
// std::tr1::bind (&B::bar, this) ();
// now ok
std::tr1::bind (&Derived::bar, derived ()) ();
}
};
struct C: B<C, A<void> >
{
};
int main ()
{
C c;
c.foo ();
return 0;
}
我发现这样的错误和解决方法是完全不合逻辑的。