我如何完成这个例子?
How do I complete this example?
你好,我正在尝试一个例子,但我不知道如何理解。
我正在尝试设置一个将所有相同 class/type 保存在一起的地图(或其他结构)。
为此,我的方法是在 class (ResourceManager_t
) 的构造函数中获取所有参数,并且每次我向地图添加新资源时,检查是否可以添加该资源,因为在 Ctor 上被接受了。
但我不知道如何填写 std::vector<>
以提供任何 type/class。
我试过 std::any
但这似乎不是正确的解决方案。
#include <iostream>
#include <memory>
#include <unordered_map>
#include <vector>
#include <type_traits>
#include <cstdint>
#include <utility>
template <typename...> struct is_one_of;
template <typename F> struct is_one_of<F> { static constexpr bool value = false; };
template <typename F, typename S, typename... T>
struct is_one_of<F, S, T...>
{
static constexpr bool value = std::is_same<F, S>::value
|| is_one_of<F, T...>::value;
};
template <typename...> struct is_unique;
template <> struct is_unique<> { static constexpr bool value = true; };
template<typename F, typename... T>
struct is_unique<F, T...>
{
static constexpr bool value = is_unique<T...>::value
&& !is_one_of<F, T...>::value;
};
template<typename... types_t>
struct ResourceManager_t
{
static constexpr inline bool areAllUnique = is_unique<types_t...>::value;
static_assert(areAllUnique);
// Ctor.
ResourceManager_t()
{
constexpr auto size = 1 + sizeof...(types_t);
m_resources.reserve(size);
}
template <typename type_t>
void addResource([[maybe_unused]] type_t add)
{
static constexpr auto oneOf = is_one_of<type_t, types_t...>::value;
static_assert(oneOf);
const auto name = typeid(type_t).name();
m_resources[name].emplace_back(add);
}
void printMap()
{
std::cout << "---------------\n";
for(auto const& [s, vi] : m_resources)
{
std::cout << "[" << s << ": ";
for(auto const& v : vi)
std::cout << static_cast<s>(v) << " ";
std::cout << "]\n";
}
std::cout << "---------------\n";
}
private:
std::unordered_map<std::string, std::vector</*TODO*/>> m_resources{};
};
int main(int, char *[])
{
ResourceManager_t<int, char, uint32_t, uint8_t> rm{};
rm.addResource(1);
rm.addResource('a');
rm.addResource(uint8_t{3U});
rm.addResource(uint8_t{6U});
// rm.addResource(3.F);
rm.printMap();
return 0;
}
我知道我的问题不是很清楚,但我已经尝试了很多方法。
我想要的例子
Map:
[int , {1, 2, 3}]
[char , {'a', 'b', 'c']
[uint8_t, {1U, 2U, 3U}]
// int, char, uint8_t can be changed with an int, or whatever that identifies my value.
如果你想要一个 compile/execute 例子,我已经用 std::vector<int>
完成了它只是为了检查所有其他参数 https://godbolt.org/z/hrb1afjxv
在我看来,您正在寻找 std::tuple<std::vector<types_t>...>
。
以下是一个完整的 C++17 编译示例,有一些简化
#include <tuple>
#include <vector>
#include <cstdint>
#include <utility>
#include <iostream>
#include <type_traits>
template <typename T0, typename ... Ts>
struct is_one_of : public std::bool_constant<(std::is_same_v<T0, Ts> || ...)>
{ };
template <typename...>
struct are_unique : public std::true_type
{ };
template <typename T0, typename ... Ts>
struct are_unique<T0, Ts...>
: public std::bool_constant<not is_one_of<T0, Ts...>::value
&& are_unique<Ts...>::value>
{ };
template <typename ... Ts>
struct ResourceManager
{
static_assert(are_unique<Ts...>::value, "not unique types");
private:
std::tuple<std::vector<Ts>...> m_resources{};
public:
ResourceManager ()
{ }
template <typename T0>
void addResource (T0 add)
{
// the static assert is superflous: you get an error from std::get
// in case of wrong type
static_assert(is_one_of<T0, Ts...>::value, "wrong type in add");
std::get<std::vector<T0>>(m_resources).emplace_back(std::move(add));
}
void printMap ()
{
auto l = [](auto const & vect)
{
std::cout << "[" << typeid(decltype(vect[0])).name() << ": ";
for (auto const & value : vect)
std::cout << value << " ";
std::cout << "]\n";
};
std::cout << "---------------\n";
std::apply([&](auto ... vects){ (l(vects), ...); }, m_resources);
std::cout << "---------------\n";
}
};
int main ()
{
ResourceManager<int, char, std::string, std::uint8_t> rm;
rm.addResource(1);
rm.addResource('a');
rm.addResource(std::uint8_t{3U});
rm.addResource<std::uint8_t>(6U);
// rm.addResource(3.F);
rm.addResource(std::string{"str1"});
rm.addResource<std::string>("longestStringForYou");
rm.printMap();
}
你好,我正在尝试一个例子,但我不知道如何理解。
我正在尝试设置一个将所有相同 class/type 保存在一起的地图(或其他结构)。
为此,我的方法是在 class (ResourceManager_t
) 的构造函数中获取所有参数,并且每次我向地图添加新资源时,检查是否可以添加该资源,因为在 Ctor 上被接受了。
但我不知道如何填写 std::vector<>
以提供任何 type/class。
我试过 std::any
但这似乎不是正确的解决方案。
#include <iostream>
#include <memory>
#include <unordered_map>
#include <vector>
#include <type_traits>
#include <cstdint>
#include <utility>
template <typename...> struct is_one_of;
template <typename F> struct is_one_of<F> { static constexpr bool value = false; };
template <typename F, typename S, typename... T>
struct is_one_of<F, S, T...>
{
static constexpr bool value = std::is_same<F, S>::value
|| is_one_of<F, T...>::value;
};
template <typename...> struct is_unique;
template <> struct is_unique<> { static constexpr bool value = true; };
template<typename F, typename... T>
struct is_unique<F, T...>
{
static constexpr bool value = is_unique<T...>::value
&& !is_one_of<F, T...>::value;
};
template<typename... types_t>
struct ResourceManager_t
{
static constexpr inline bool areAllUnique = is_unique<types_t...>::value;
static_assert(areAllUnique);
// Ctor.
ResourceManager_t()
{
constexpr auto size = 1 + sizeof...(types_t);
m_resources.reserve(size);
}
template <typename type_t>
void addResource([[maybe_unused]] type_t add)
{
static constexpr auto oneOf = is_one_of<type_t, types_t...>::value;
static_assert(oneOf);
const auto name = typeid(type_t).name();
m_resources[name].emplace_back(add);
}
void printMap()
{
std::cout << "---------------\n";
for(auto const& [s, vi] : m_resources)
{
std::cout << "[" << s << ": ";
for(auto const& v : vi)
std::cout << static_cast<s>(v) << " ";
std::cout << "]\n";
}
std::cout << "---------------\n";
}
private:
std::unordered_map<std::string, std::vector</*TODO*/>> m_resources{};
};
int main(int, char *[])
{
ResourceManager_t<int, char, uint32_t, uint8_t> rm{};
rm.addResource(1);
rm.addResource('a');
rm.addResource(uint8_t{3U});
rm.addResource(uint8_t{6U});
// rm.addResource(3.F);
rm.printMap();
return 0;
}
我知道我的问题不是很清楚,但我已经尝试了很多方法。 我想要的例子
Map:
[int , {1, 2, 3}]
[char , {'a', 'b', 'c']
[uint8_t, {1U, 2U, 3U}]
// int, char, uint8_t can be changed with an int, or whatever that identifies my value.
如果你想要一个 compile/execute 例子,我已经用 std::vector<int>
完成了它只是为了检查所有其他参数 https://godbolt.org/z/hrb1afjxv
在我看来,您正在寻找 std::tuple<std::vector<types_t>...>
。
以下是一个完整的 C++17 编译示例,有一些简化
#include <tuple>
#include <vector>
#include <cstdint>
#include <utility>
#include <iostream>
#include <type_traits>
template <typename T0, typename ... Ts>
struct is_one_of : public std::bool_constant<(std::is_same_v<T0, Ts> || ...)>
{ };
template <typename...>
struct are_unique : public std::true_type
{ };
template <typename T0, typename ... Ts>
struct are_unique<T0, Ts...>
: public std::bool_constant<not is_one_of<T0, Ts...>::value
&& are_unique<Ts...>::value>
{ };
template <typename ... Ts>
struct ResourceManager
{
static_assert(are_unique<Ts...>::value, "not unique types");
private:
std::tuple<std::vector<Ts>...> m_resources{};
public:
ResourceManager ()
{ }
template <typename T0>
void addResource (T0 add)
{
// the static assert is superflous: you get an error from std::get
// in case of wrong type
static_assert(is_one_of<T0, Ts...>::value, "wrong type in add");
std::get<std::vector<T0>>(m_resources).emplace_back(std::move(add));
}
void printMap ()
{
auto l = [](auto const & vect)
{
std::cout << "[" << typeid(decltype(vect[0])).name() << ": ";
for (auto const & value : vect)
std::cout << value << " ";
std::cout << "]\n";
};
std::cout << "---------------\n";
std::apply([&](auto ... vects){ (l(vects), ...); }, m_resources);
std::cout << "---------------\n";
}
};
int main ()
{
ResourceManager<int, char, std::string, std::uint8_t> rm;
rm.addResource(1);
rm.addResource('a');
rm.addResource(std::uint8_t{3U});
rm.addResource<std::uint8_t>(6U);
// rm.addResource(3.F);
rm.addResource(std::string{"str1"});
rm.addResource<std::string>("longestStringForYou");
rm.printMap();
}