【发布时间】:2014-08-05 16:35:13
【问题描述】:
这个问题来自here,与当元组的元素通过模板定义时访问元组元素有关。
如果我有访问元组内容的方法:
#include <cstdint>
#include <type_traits>
#include <tuple>
namespace detail
{
template <typename T, typename... Ts> struct get_index;
template <typename T, typename... Ts>
struct get_index<T, T, Ts...> : std::integral_constant<std::size_t, 0> {};
template <typename T, typename Tail, typename... Ts>
struct get_index<T, Tail, Ts...> :
std::integral_constant<std::size_t, 1 + get_index<T, Ts...>::value> {};
template <typename T>
struct get_index<T> : std::integral_constant<std::size_t, 0> {}; // Not found
template <std::size_t N, typename... Ts>
constexpr
auto
safe_get(const std::tuple<Ts...>& t) noexcept
-> typename std::enable_if<N < sizeof...(Ts), decltype(&std::get<N < sizeof...(Ts) ? N : 0>(t))>::type
{
return &std::get<N>(t);
}
template <std::size_t N, typename... Ts>
constexpr
auto
safe_get(const std::tuple<Ts...>&) noexcept
-> typename std::enable_if<sizeof...(Ts) <= N, nullptr_t>::type
{
return nullptr;
}
}
我想在这里访问元组元素,但是每个元组元素都是通过模板创建的。因此:
class BaseElement {
public:
virtual int polymorphicFunction() {return 0;};
};
template <uint32_t exampleParameter = 1>
class DerivedElement1 : public BaseElement {
public:
DerivedElement1() : i(exampleParameter) {}
virtual int polymorphicFunction() {return 1;};
uint32_t i; /// just used as a placeholder to demo use of parameter
}
template <uint32_t exampleParameter = 2>
class DerivedElement2 : public BaseElement {
public:
DerivedElement2() : i(exampleParameter) {}
virtual int polymorphicFunction() {return 2;};
uint64_t i; /// just used as a placeholder to demo use of parameter (class is different to DE1)
}
template<typename... systems> // systems will always be of derived class of BaseElement
class System {
System() : subsystems(systems{}...),
pd1(detail::safe_get<detail::get_index<DerivedElement1, systems...>::value>(subSystems)),
pd2(detail::safe_get<detail::get_index<DerivedElement2, systems...>::value>(subSystems))
{} // all variadic elements stored in tuple
const std::tuple<systems...> subSystems;
DerivedElement1<> *pd1;
DerivedElement2<> *pd2;
};
pd1 & pd2 应设置为指向各自的派生元素,如果它们在 System 的声明中指定时存在,则应设置为 null。
这在我这样做时有效:
System<DerivedElement1<>, DerivedElement2<>> sys; // sys.pd1 points to DerivedElement1<> element of tuple, sys.pd2 points to DerivedElement2<> within tuple
但如果我为 System 的声明提供一个变量,pd1 和 pd2 都设置为 nullptr。
System<DerivedElement1<5>, DerivedElement2<6>> sys; // sys.pd1 == nullptr, sys.pd2 == nullptr
请问如何让 pd1 和 pd2 指向正确的元组元素?
编辑以使其更清晰:
从一个公共类派生的不同类型存储在一个元组中(例如 DerivedElement1、DerivedElement2)。我在存储类指针中应该指向元组的派生类元素。当我不使用模板参数(即上面示例中的 DerivedElement1)时,我的设置指针代码有效,但当我使用模板参数(例如 DerivedElement1)时无效。
【问题讨论】:
-
您要么需要简化示例,要么显示实际代码,因为这已经足够混乱和不完整了。
-
恐怕这很简单,我无法发布真正的代码:出于某种原因(我认为这是因为我提供了一个模板参数,而不是使用默认值一),访问元组元素失败,我得到 nullptr 返回。
-
它也不会编译,因为您将模板 DerivedElement1 和 DerivedElement2 传递给 detail::get_index,它需要一个类型参数,而不是模板参数。
-
您到底在尝试什么?这是没有意义的,因为
DerivedElementX是模板,但是您将它们传递给您的类型列表搜索工具(get_index,它获取给定类型列表中传递类型的索引,不是吗?)。请更清楚。 -
对不起 - 这里的原始问题 (stackoverflow.com/questions/24831352/…) 使用类型,因为该问题是一个简化。也就是说,DerivedElement1 是一种类型,而不是模板,DerivedElement1 也是如此(详情:stackoverflow.com/questions/24812913/…)
标签: c++ templates tuples variadic-templates variadic-functions