Can anyone tell me why std::get<T>
of C++17 is a global function and not a member-function of variant<...>
?
Asked
Active
Viewed 1,171 times
10

Nicol Bolas
- 449,505
- 63
- 781
- 982

Bonita Montero
- 2,817
- 9
- 22
-
9I'll ask the complementary question: why should it be a member function? – Pete Becker Feb 05 '17 at 20:53
-
8[Same as for tuple](https://stackoverflow.com/questions/3313479/stdtuple-get-member-function) most certainly. The syntax gets too ugly. – Baum mit Augen Feb 05 '17 at 20:53
-
1@PeteBecker: Discoverability, intuition, consistency with other containers. – Dwayne Robinson Nov 21 '18 at 04:37
1 Answers
9
If get<T>()
were a member function template, a template
keyword would be needed when it is called in a dependent context. For example:
template <typename Variant>
void f(Variant const& v) {
auto x0 = v.template get<T>(); // if it were a member
auto x1 = get<T>(v); // using a non-member function
}
Even without a using
declaration or directive get()
is found as both std::variant<...>
and get()
are declared in namespace std
. Thus, there seems to be no good reason to make it a member function as the global function is easier to use.

Dietmar Kühl
- 150,225
- 13
- 225
- 380
-
1Well, you need a function template named `get` in scope for `get
(v)` to be parsed correctly. Still, better than having to write `template` at every turn. – T.C. Feb 06 '17 at 10:17 -
@T.C.: good point - with the template parameter it isn't directly found via ADL. That may argue for an uncallable function template being declared at global scope (e.g., `template
typename T::uncallable get();`; the number of arguments don't really matter...). – Dietmar Kühl Feb 06 '17 at 10:46 -
2Why is `emplace()` a member then? That doesn't seem to need the `template` keyword: https://en.cppreference.com/w/cpp/utility/variant/emplace – ShdNx Oct 21 '19 at 21:40
-
2@ShdNx: the problem is with parsing member function templates with explicitly specified template arguments: while `get
(v)` inherently requires that `T` gets specified, `v.emplace(a...)` desuces all its template parameters. Hence, the problem doesn’t exist over there. – Dietmar Kühl Oct 22 '19 at 12:56 -
2@DietmarKühl: actually, you need to explicitly specify `T` for `emplace`, otherwise it doesn't know what to try to construct from the arguments given. See my earlier link to cppreference.com for examples. – ShdNx Oct 22 '19 at 17:42
-
@ShdNx: interesting - I didn’t realize that `std::variant::emplace` also takes an explicit template argument. Of course, that means that you’ll need to write `v.template emplace
(a...)` in contexts where `v`’s type is a template parameter. The implication is that the designers of `std::variant` assumed that `emplace` is normally used on objects with a non-dependent name. – Dietmar Kühl Oct 24 '19 at 18:15