对于相对较旧的软件中的某些序列化应用程序,我的类型看起来像这样:
using T = boost::tuple<
std::pair<std::integral_constant<uint32_t, 0>, std::vector<int>>,
std::pair<std::integral_constant<uint32_t, 1>, std::vector<double>>
>;
T events;
这些常数为static constexpr
,代表某些数据库表,向量为某种存储类型(细节不重要)。
为了确保这种“类型”类型的安全,并确保将来一切正常,我需要确保在元组中添加其他类型的用户使用序列号。所以另一个元素应该是这个:
using T = boost::tuple<
std::pair<std::integral_constant<uint32_t, 0>, std::vector<int>>,
std::pair<std::integral_constant<uint32_t, 1>, std::vector<double>>,
std::pair<std::integral_constant<uint32_t, 2>, std::vector<float>>
>;
T events;
这是错误,不应该编译:
using T = boost::tuple<
std::pair<std::integral_constant<uint32_t, 0>, std::vector<int>>,
std::pair<std::integral_constant<uint32_t, 1>, std::vector<double>>,
std::pair<std::integral_constant<uint32_t, 1>, std::vector<float>>
>;
T events;
[我的解决方案到目前为止失败了,我很感谢有人对此提供意见:
template <typename Tuple>
struct tuple_assert;
template <typename... Ts>
struct tuple_assert<boost::tuple<Ts...>> {
static constexpr void verify() {
__verify<std::integral_constant<uint32_t, 0>, Ts...>();
}
static constexpr void __verify() {}
template <typename Count, typename Pair>
static constexpr void __verify() {
static_assert(std::is_same<typename Pair::first_type, Count>::value, "");
}
template <typename Count, typename Pair, typename... Ts2>
static constexpr void __verify() {
static_assert(std::is_same<typename Pair::first_type, Count>::value, "");
__verify<std::integral_constant<uint32_t, Pair::first_type::value + 1>,
Ts...>();
}
};
所以您看到的是我创建了一个状态(Count
),并且每次迭代都在增加计数。但这以某种方式达到了错误的状态,当我在此调用中使用它时会触发static_assert:
tuple_assert<T>::verify(); // `T` is the type I mentioned at the very beginning
See my solution that doesn't work online.
我在做什么错?
您的代码有些错误。第一个是在此行中,模板参数列表扩展中的错字:
__verify<std::integral_constant<uint32_t, Pair::first_type::value + 1>,
Ts...>();
应该是:
__verify<std::integral_constant<uint32_t, Pair::first_type::value + 1>,
Ts2...>();
但是可惜它无法解决。 boost::tuple
里面有一些nulltype_t
奇怪的typedef。将其更改为std::tuple
仍无法解决,因为您的__verify
函数调用不明确。
这是我所做的肯定有效的方法:
template<unsigned V, class T, class ...Args>
struct verify_types {
static constexpr bool value = V == T::first_type::value && verify_types<V+1, Args...>::value;
};
template<unsigned V, class T>
struct verify_types<V, T> {
static constexpr bool value = V == T::first_type::value;
};
template<class T>
struct verify_tuple : std::false_type {};
template<class ...Args>
struct verify_tuple<std::tuple<Args...>> : verify_types<0, Args...>{};