Apparently clang thinks decltype(this)
is a pointer to the cv-qualified class, while gcc thinks it is a const reference to a pointer to the cv-qualified class. GCC only thinks decltype(&*this)
is a pointer to the cv-qualified class. This has some implications when it is used as the typename for a template. Consider a hypothetical example:
template<typename T>
class MyContainer {
/* ... */
template<typename ContainerPtr>
class MyIterator {
ContainerPtr container;
/* ... */
};
auto cbegin() const
-> MyIterator<decltype(&*this)> { return { /* ... */ }; }
auto cend() const
-> MyIterator<decltype(this)> { return { /* ... */ }; }
};
In this example, one implements a custom container of T
. Being a container, it supports iterators. In fact, two kinds of iterators: iterator
s and const_iterator
s. It would not make sense to duplicate the code for these two, so one could write a template iterator class, taking either a pointer to the original class MyContainer<T> *
or a pointer to the const version MyContainer<T> const *
.
When cbegin
and cend
are used together, gcc errors out, saying it deduced conflicting types, while clang just works fine.