英文:
entt basic_registry::get<>() explanation
问题
Currently using g++11.3.0, C++20.
Could anyone explain how the basic_registry's get<>()
template function is able to function such that when retrieving a single component through a call like auto& comp {registry.get<A>()};
, the component itself can be directly assigned to and/or accessed like a normal reference, and when retrieving multiple components through a call like registry.get<A, B, C>()
, it can be unpacked via a structured binding auto& [a, b, c]
.
Code (from https://skypjack.github.io/entt/registry_8hpp_source.html)
template<typename... Type>
[[nodiscard]] decltype(auto) get([[maybe_unused]] const entity_type entt) {
if constexpr(sizeof...(Type) == 1u) {
return (const_cast<Type &&>(std::as_const(*this).template get<Type>(entt)), ...);
} else {
return std::forward_as_tuple(get<Type>(entt)...);
}
}
英文:
Currently using g++11.3.0, C++20.
Could anyone explain how the basic_registry's get<>()
template function is able to function such that when retrieving a single component through a call like auto& comp {registry.get<A>()};
, the component itself can be directly assigned to and/or accessed like a normal reference, and when retrieving multiple components through a call like registry.get<A, B, C>()
, it can be unpacked via a structured binding auto& [a, b, c]
.
Code (from https://skypjack.github.io/entt/registry_8hpp_source.html)
template<typename... Type>
[[nodiscard]] decltype(auto) get([[maybe_unused]] const entity_type entt) {
if constexpr(sizeof...(Type) == 1u) {
return (const_cast<Type &>(std::as_const(*this).template get<Type>(entt)), ...);
} else {
return std::forward_as_tuple(get<Type>(entt)...);
}
}
答案1
得分: 1
以下是代码部分的翻译:
// 以下函数模板返回一个元组:
template <typename ...T>
auto foo() {
return std::make_tuple(T{}...);
}
// 您可以通过以下方式调用它:
auto [a, b, c] = foo<int, int, double>();
// 以下函数模板仅返回一个 'T':
template <typename T>
auto bar() { return T{}; }
// 您可以通过以下方式调用它:
auto d{bar<int>()};
// 函数只能有一个返回类型。'foo' 和 'bar' 是函数模板。函数 'foo<int, int, double>' 和 'bar<int>' 有一个返回类型。它们返回一个值。
// 以下函数模板根据模板参数的数量选择要实例化和调用的两个函数模板之一:
template <typename ...T>
auto moo() {
if constexpr(sizeof...(T) == 1u) { return bar<T...>(); }
else return foo<T...>();
}
// 您可以通过以下方式调用它:
auto [x, y, z] = moo<int, int, double>();
// 或者
auto w{moo<int>()};
// 请注意,当 'T...' 多于一个参数时,'bar<T...>' 会不匹配(因为 'bar' 只有一个参数)。然而,在模板上下文中,未选择的分支在编译时会被丢弃。
// 在 'sizeof...(T) == 1u' 的情况下,参数包被展开。然而,在这种情况下,展开只有一个类型(否则 'bar<T...>' 将无法编译)。它可以写成:
template <typename T, typename ...More>
auto moo() {
if constexpr(sizeof...(More) == 0u) { return bar<T>(); }
else return foo<T, More...>();
}
// [在线演示](https://godbolt.org/z/n6MrYqd36)
这是代码的翻译部分,不包括问题的回答。
英文:
The following function template returns a tuple:
template <typename ...T>
auto foo() {
return std::make_tuple(T{}...);
}
You can call it via
auto [a, b, c] = foo<int,int,double>();
The following function template returns just a T
:
template <typename T>
auto bar() { return T{};}
you can call it via
auto d{bar<int>()};
Functions can have only one return type. foo
and bar
are function templates. The functions foo<int,int,double>
and bar<int>
have one return type. They return one value.
The following function template selects between two function templates to be instantiated and called depending on the number of template arguments:
template <typename ...T>
auto moo() {
if constexpr(sizeof...(T) == 1u) { return bar<T...>(); }
else return foo<T...>();
}
You can call it via:
auto [x,y,z] = moo<int,int,double>();
Or
auto w{ moo<int>()};
Note that when T...
is more than a single argument then bar<T...>
would be a mismatch (because bar
has only a single argument. However, with constexpr if
in template context the not taken branch is discarded at compile time.
In the case of sizeof...(T) == 1u
the parameter pack is expanded. However, the expansion is only a single type in this case (otherwise bar<T...>
would not compile). It could have been written as
template <typename T,typename ...More>
auto moo() {
if constexpr(sizeof...(More) == 0u) { return bar<T>(); }
else return foo<T,More...>();
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论