The following code does not compile (tested with MSVC 19.28 with /std:c++latest and Clang 12.0 with -std=c++20 on godbolt.org):
#include <variant>
struct some_thing;
using var = std::variant<some_thing>;
// There should be NO need to instantiate the template here, right?
void take(var* v) {}
int main() {
var* v = nullptr;
take(v); // This is the offending line - tries to instantiate the variant template and fails as 'some_thing' is undefined up until now.
return 0;
}
How would the call to take in main require a template instantiation? We just hand around a pointer. Is this a bug or am I missing something?
Template instantiation should not occur if working with a pointer type of the template (as I'm doing it) and not when typedef'ing it as typedefs do not introduce new types (i.e. instances of templates). I might still be missing something but this should enable my example code to compile.
Please see the MSVC error message(s) below. Please note that this question is not about understanding the error message(s). Its about why there even is a template instantiation happening in the first place.
C:/data/msvc/14.28.29333/include\type_traits(807): error C2139: 'some_thing': an undefined class is not allowed as an argument to compiler intrinsic type trait '__is_trivially_destructible'
<source>(3): note: see declaration of 'some_thing'
C:/data/msvc/14.28.29333/include\variant(956): note: see reference to class template instantiation 'std::is_trivially_destructible<some_thing>' being compiled
C:/data/msvc/14.28.29333/include\variant(956): note: see reference to variable template 'const bool conjunction_v<std::is_trivially_destructible<some_thing> >' being compiled
C:/data/msvc/14.28.29333/include\variant(1014): note: see reference to alias template instantiation 'std::_Variant_destroy_layer<some_thing>' being compiled
<source>(11): note: see reference to class template instantiation 'std::variant<some_thing>' being compiled
C:/data/msvc/14.28.29333/include\type_traits(661): error C2139: 'some_thing': an undefined class is not allowed as an argument to compiler intrinsic type trait '__is_constructible'
<source>(3): note: see declaration of 'some_thing'
C:/data/msvc/14.28.29333/include\xsmf_control.h(61): note: see reference to class template instantiation 'std::is_move_constructible<some_thing>' being compiled
C:/data/msvc/14.28.29333/include\xsmf_control.h(62): note: see reference to variable template 'const bool conjunction_v<std::is_move_constructible<some_thing>,std::negation<std::conjunction<std::is_trivially_move_constructible<some_thing> > > >' being compiled
C:/data/msvc/14.28.29333/include\xsmf_control.h(100): note: see reference to alias template instantiation 'std::_SMF_control_move<std::_Variant_destroy_layer_<some_thing>,some_thing>' being compiled
C:/data/msvc/14.28.29333/include\xsmf_control.h(139): note: see reference to alias template instantiation 'std::_SMF_control_copy_assign<std::_Variant_destroy_layer_<some_thing>,some_thing>' being compiled
C:/data/msvc/14.28.29333/include\xsmf_control.h(146): note: see reference to alias template instantiation 'std::_SMF_control_move_assign<std::_Variant_destroy_layer_<some_thing>,some_thing>' being compiled
C:/data/msvc/14.28.29333/include\variant(1014): note: see reference to alias template instantiation 'std::_SMF_control<std::_Variant_destroy_layer_<some_thing>,some_thing>' being compiled
C:/data/msvc/14.28.29333/include\type_traits(630): error C2139: 'some_thing': an undefined class is not allowed as an argument to compiler intrinsic type trait '__is_constructible'
<source>(3): note: see declaration of 'some_thing'
C:/data/msvc/14.28.29333/include\xsmf_control.h(39): note: see reference to class template instantiation 'std::is_copy_constructible<some_thing>' being compiled
C:/data/msvc/14.28.29333/include\xsmf_control.h(40): note: see reference to variable template 'const bool conjunction_v<std::is_copy_constructible<some_thing>,std::negation<std::conjunction<std::is_trivially_copy_constructible<some_thing> > > >' being compiled
C:/data/msvc/14.28.29333/include\xsmf_control.h(63): note: see reference to alias template instantiation 'std::_SMF_control_copy<std::_Variant_destroy_layer_<some_thing>,some_thing>' being compiled
C:/data/msvc/14.28.29333/include\variant(491): error C2079: 'std::_Variant_storage_<false,some_thing>::_Head' uses undefined struct 'some_thing'
C:/data/msvc/14.28.29333/include\variant(838): note: see reference to class template instantiation 'std::_Variant_storage_<false,some_thing>' being compiled
C:/data/msvc/14.28.29333/include\variant(941): note: see reference to class template instantiation 'std::_Variant_base<some_thing>' being compiled
C:/data/msvc/14.28.29333/include\xsmf_control.h(85): note: see reference to class template instantiation 'std::_Variant_destroy_layer_<some_thing>' being compiled
C:/data/msvc/14.28.29333/include\xsmf_control.h(124): note: see reference to class template instantiation 'std::_Deleted_copy_assign<std::_Variant_destroy_layer_<some_thing>,some_thing>' being compiled
C:/data/msvc/14.28.29333/include\variant(1014): note: see reference to class template instantiation 'std::_Deleted_move_assign<std::_Variant_destroy_layer_<some_thing>,some_thing>' being compiled
C:/data/msvc/14.28.29333/include\type_traits(730): error C2139: 'some_thing': an undefined class is not allowed as an argument to compiler intrinsic type trait '__is_destructible'
<source>(3): note: see declaration of 'some_thing'
C:/data/msvc/14.28.29333/include\variant(1016): note: see reference to class template instantiation 'std::is_destructible<some_thing>' being compiled
C:/data/msvc/14.28.29333/include\variant(1016): note: see reference to variable template 'const bool conjunction_v<std::is_object<some_thing>,std::negation<std::is_array<some_thing> >,std::is_destructible<some_thing> >' being compiled
C:/data/msvc/14.28.29333/include\variant(1016): error C2338: variant<Types...> requires all of the Types to meet the Cpp17Destructible requirements N4828 [variant.variant]/2.
Compiler returned: 2