On Tuesday 10 December 2013 09:32:11 Matt Calabrese wrote:
On Tue, Dec 10, 2013 at 5:54 AM, Andrey Semashev
wrote: I think that case would better be handled by variant<blank>. I.e. you can replace void return types with blank and the rest of the code can be left intact.
While that is the current workaround, I look at it as exactly that -- a work-around. It just seems very arbitrary to me and only makes it so that people have to special-case for a logical variant<> in metaprogrammed code. As Peter Dimov also pointed out, variant<> seems to be just as valid as a union {}, and I think most people would expect it to work pretty much the same way. I also don't think we'd lose anything by simply supporting it and the implementation would be trivial.
The problem is that, as opposed to union, variant provides advanced APIs which loose their meaning if no type is specified. Making variant<> a special case with its own set of APIs makes generic programming more difficult since you have to propagate support for that special case through all surrounding templates. And on top of that the special case adds variant implementation complexity for little-to-no outcome. If variant<> is really desired, it has to support all the APIs that are defined now for the non-empty variant. You can achieve that by making it always non-empty with a reasonable default, e.g.: template< typename T0 = blank, typename... TN > class variant;