Consider the following code:
template <class Derived>
class KFBase
{
public:
template <typename Nom>
struct State {
Nom nominal_state;
};
};
template <typename A>
class PFilter
: public KFBase<PFilter<A>>
{
public:
using Base = KFBase<PFilter<A>>;
// comment this out and it works
using State = typename Base::State<int>;
};
int main(int, char**){
PFilter<int>{};
}
As hinted in the comment, if I comment out the State alias everything compiles fine on MSVC. However, if I include it, I get a compile error when compiling with C++17 or C++20 (https://godbolt.org/z/aM78ToMsc), but rolling back to C++14 it works again on MSVC (https://godbolt.org/z/Eej9bjrf7)
On GCC this compiles just fine with C++20, so I'm wondering if I'm following the C++ standard or this is a bug introduced in the C++17 MSVC implementation.
My gut feeling is that this has something to do with CTAD, but I'm not sure.
Anyone can elucidate here?
P.S. If anyone has a better title for this question, please let me know.
You might need a template
to indicate that <
is not a comparison
using State = typename Base::template State<int>;
MSVC is pretty lax in C++14 mode (because at the time it was). Later versions have a /permissive-
flag turned on by default.
In later standards you can instead remove the typename
, because using
is now known to always require a type following the =
. This is complicated. :-)
Perhaps gcc also has a more permissive mode by default, I don't know.