稍微修改了一下你的原答案,不好意思可能写得有点乱,有些地方很冗余。在
https://wandbox.org/上简单的测试过~ 出错的地方还请大家指教 ;)
```c++
#include <vector>
#include <tuple>
using namespace std;
template <typename... Ts>
struct my_tuple;
template<typename A, typename B>
struct tuple_contains;
template <typename checkT>
struct tuple_contains<std::tuple<>, checkT>
{
constexpr static bool value = false;
};
template <typename headT, typename checkT>
struct tuple_contains<std::tuple<headT>, checkT>
{
constexpr static bool value = std::is_same<headT, checkT>::value;
};
template <typename headT, typename... tailT, typename checkT>
struct tuple_contains<std::tuple<headT, tailT...>, checkT>
{
constexpr static bool value = std::is_same<headT, checkT>::value || tuple_contains<std::tuple<tailT...>, checkT>::value;
};
template<typename A, typename B>
struct tuple_count;
template <typename checkT>
struct tuple_count<std::tuple<>, checkT>
{
constexpr static size_t value = 0;
};
template <typename headT, typename checkT>
struct tuple_count<std::tuple<headT>, checkT>
{
constexpr static size_t value = std::is_same<headT, checkT>::value ? 1 : 0;
};
template <typename headT, typename... tailT, typename checkT>
struct tuple_count<std::tuple<headT, tailT...>, checkT>
{
constexpr static size_t value = (std::is_same<headT, checkT>::value ? 1 : 0 ) + tuple_count<std::tuple<tailT...>, checkT>::value;
};
template<typename A>
struct check_tuple_unique;
template<>
struct check_tuple_unique<std::tuple<>>
{
constexpr static bool value = true;
};
template <typename headT>
struct check_tuple_unique<std::tuple<headT>>
{
constexpr static bool value = true;
};
template <typename headT, typename... tailT>
struct check_tuple_unique<std::tuple<headT, tailT...>>
{
constexpr static bool value = (tuple_count<std::tuple<tailT...>, headT>::value == 0) && check_tuple_unique<std::tuple<tailT...>>::value == true;
};
template<typename A, typename B, typename C>
struct index_of_details;
template <typename... leftT, typename headT, typename checkT>
struct index_of_details<std::tuple<leftT...>, std::tuple<headT>, checkT>
{
constexpr static size_t value = std::is_same<headT, checkT>::value ? tuple_size<std::tuple<leftT...>>::value : -1;
};
template <typename... leftT, typename headT, typename... tailT, typename checkT>
struct index_of_details<std::tuple<leftT...>, std::tuple<headT, tailT...>, checkT>
{
constexpr static size_t value = std::is_same<headT, checkT>::value ? tuple_size<std::tuple<leftT...>>::value : index_of_details<std::tuple<leftT..., headT>, std::tuple<tailT...>, checkT>::value;
};
template<typename A, typename B>
struct index_of;
template <typename checkT, typename... tailT>
struct index_of<std::tuple<tailT...>, checkT>
{
constexpr static size_t value = index_of_details<std::tuple<>, std::tuple<tailT...>, checkT>::value;
};
template <typename... Ts>
struct my_tuple {
using T = std::tuple<Ts...>;
template <typename... Ks>
using append = my_tuple<Ts..., Ks...>;
my_tuple()
{
static_assert(check_tuple_unique<T>::value, "Wakaka! duplicated found!");
}
T instance;
template <std::size_t I>
std::tuple_element_t<I, T>& get() {
return std::get<I>(instance);
}
template<typename targetT>
auto& get() {
return std::get<index_of<T, targetT>::value>(instance);
}
};
int main()
{
static_assert(tuple_contains<std::tuple<>, int>::value == false, "wrong answer");
static_assert(tuple_contains<std::tuple<int>, int>::value == true, "wrong answer");
static_assert(tuple_contains<std::tuple<double, double>, int>::value == false, "wrong answer");
static_assert(tuple_count<std::tuple<>, int>::value == 0, "wrong answer");
static_assert(tuple_count<std::tuple<int>, int>::value == 1, "wrong answer");
static_assert(tuple_count<std::tuple<int, double, int>, int>::value == 2, "wrong answer");
static_assert(check_tuple_unique<std::tuple<>>::value == true, "wrong answer");
static_assert(check_tuple_unique<std::tuple<int>>::value == true, "wrong answer");
static_assert(check_tuple_unique<std::tuple<int, double, int>>::value == false, "wrong answer");
static_assert(check_tuple_unique<std::tuple<int, int>>::value == false, "wrong answer");
static_assert(check_tuple_unique<std::tuple<int, double, std::vector<int>>>::value == true, "wrong answer");
// this will fail
// auto tuple = my_tuple<int>::append<float, char, long>
// ::append<bool, double>
// ::append<std::vector<int>, int>();
auto tuple = my_tuple<int>::append<float, char, long>
::append<bool, double>
::append<std::vector<int>>();
std::vector<int>& vector = tuple.get<6>();
std::vector<int>& vector2 = tuple.get<std::vector<int>>();
auto tuple2 = my_tuple<int>::append<std::vector<int>>();
std::vector<int>& vector3 = tuple.get<std::vector<int>>();
int& vector4 = tuple.get<int>();
}
```