I'm trying to implement a generic function that generates a std::string
from an id (which is an std::pair<uint32_,uint32_t>
).
The function is the following:
typedef uint32_t element_type;
template <element_type type>
std::string to_string (const std::pair<element_type, uint32_t>& id) {
....
const char* name = elemen_type_traits<type>::element_type_name;
...
}
I can invoke the function in the following way:
std::cout << to_string<ELEMENT_TYPE_FOO> (foo_0) << std::endl;
std::cout << to_string<ELEMENT_TYPE_FOO> (foo_1) << std::endl;
The only thing is that I want to make sure that the template parameter matches the first field of the std::pair
. Is it possible to deduct the parameter value from std::pair.first
?
I don't know if it's possible but in the end I would like to have something like this:
std::cout << to_string (foo_0) << std::endl;
std::cout << to_string (foo_1) << std::endl;
Thanks in advance.
If you encode the value inside a type, this is actually achievable:
// C++11 'enum class' emulation, you don't want to leak 'foo' everywhere
// also called a "scoped enum"
struct element_type_value{
enum type{
foo = 1337
};
};
template<element_type_value::type V>
struct element_type{};
template<element_type_value::type V>
std::string to_string(std::pair<element_type<V>, uint32_t> const& /*id*/){
// ...
const char* name = element_type_traits<V>::element_type_name;
// ...
}
Of course, this only works if the type is always a statically known value, and actually you don't even need the id.first
anymore. However, there's no other way of achieving this check, as far as I know.
I personally would probably drop std::pair
and just make a custom struct, together with some other refactoring.
struct element_type{
enum type{
foo = 1337
};
};
template<element_type::type V>
struct element_type_id{
element_type_id(uint32_t id) : id(id){}
uint32_t id; // or whatever your original std::pair::second represented
};
template<element_type::type V>
std::string to_string(element_type_id<V> const& /*id*/){
// ...
const char* name = element_type_traits<V>::element_type_name;
// ...
}