【发布时间】:2021-09-21 09:23:06
【问题描述】:
以下代码无法编译(在 godbolt.org 上使用 MSVC 19.28 和 /std:c++latest 和 Clang 12.0 和 -std=c++20 测试):
#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;
}
调用 main 需要模板实例化吗?我们只是传递一个指针。这是一个错误还是我错过了什么?
Template instantiation 不应该发生在使用模板的指针类型(正如我正在做的那样)而不是当 typedef'ing 它作为 typedef 不引入新类型(即模板实例)时。我可能仍然遗漏了一些东西,但这应该使我的示例代码能够编译。
请参阅下面的 MSVC 错误消息。请注意,此问题不是关于理解错误消息的问题。它是关于为什么首先会发生模板实例化的原因。
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
【问题讨论】:
-
很抱歉,您是否阅读了我的问题及其编辑内容?链接到的问题与我的问题并不真正相关,因为它包含
std::vector<Shape> shapes;显然不会编译,因为 Shape 必须在此处实例化为它用作值(而不是作为指针,如我的问题)。 -
"转发声明
std::variant"。作为未定义的行为,这是不可能的。 -
感谢您的提示。我试图集中注意力并删除了前向声明案例。
-
我当然从这个问题中学到了一些东西。我现在知道我上面的 cmets 大多是错误的。我删除了它们,不要混淆其他人,你可能也想清理你的 cmets
标签: c++ templates compiler-errors forward-declaration