The following code doesn't work if class some_class is templated. So my guess is that I have to put the template specifier in front of something, but I don't really know where? I tried putting it in front of state::base and state::error types within the variant definition, but this doesn't work. Where do I put it and why?
#include <variant>
template <typename T>
class some_class
{
void do_something() {
struct state {
struct base{};
struct error{};
};
std::variant<state::base, state::error> fsm{};
}
};
int main() {}
Error:
<source>:12:47: error: type/value mismatch at argument 1 in template parameter list for 'template<class ... _Types> class std::variant'
12 | std::variant<state::base, state::error> fsm{};
| ^
<source>:12:47: note: expected a type, got 'some_class<T>::do_something()::state::base'
<source>:12:47: error: type/value mismatch at argument 1 in template parameter list for 'template<class ... _Types> class std::variant'
<source>:12:47: note: expected a type, got 'some_class<T>::do_something()::state::error'
The compiler considers
state::baseandstate::errorto be dependent (on the template arguments), in which case they would require prefixing withtypenameso that they are considered types while parsing the class template definition.However, intuitively these names/types seem like they shouldn't be dependent. Although the type is a different one for each specialization of the enclosing class template, it is guaranteed that
state::basewill always name and refer to a known type in the function definition for every instantiation of the enclosing template. This can't be changed e.g. via explicit or partial specialization.This seems to be an open CWG issue (CWG 2074). The standard currently does not say that these names are dependent. They would be dependent only if the local classes contained a dependent type (see [temp.dep.type]/9.5), but they don't do that in your case. Still it seems some compilers consider these types to be dependent.
So your solution is to prefix them with
typenameeven if that is probably not required or intended per standard.