I am trying to define a generic container with a template parameter. There are predefined values to pick from for the template parameter. For convenience, I would like to also allow passing integer values as an alternative, and have them mapped automatically to the corresponding predefined value.
For example (this does not work):
struct Option {
Option(unsigned int);
};
static Option A(1);
static Option B(2);
template<Option& o>
class Value {};
Value<B> b;
Value<2> c; // <-- this is not permitted
(bonus question: same problem but the alternative value is a type, for ex: uint8_t -> 1, uint32_t -> 2)
There is no safe or standard way to get the desired effect, and if you reach a point where this begins to look like a viable option, I would strongly recommend reconsidering your design. However, if you are insistent, you have a c++17 compiler, and you are willing to use pointers instead of references, you can use non-type template parameter deduction, with SFINAE, to get the desired effect:
#include<type_traits>
struct Option{
Option(unsigned int);
}
static Option A(1);
static Option A(2);
//enable this template if the non-type template parameter is a pointer-to-Option,
// or an unsigned int can be constructed from the parameter
template<auto I, typename=std::enable_if_t<
std::is_same_v<decltype(I), Option*> ||
std::is_constructible_v<uint, decltype(I)>
>>
class Value{
};
Value<&B> b;
Value<2> c;
This will work, and it is fairly straight forward to add support for more types. However, using the template parameter is not trivial, and will require a solution that is dependent on how you plan to use the template parameter.
Based on your code above, I would consider using enum classes instead, which may provide a far more suitable alternative:
enum class Option{
A=1,B=2
};
template<Option o>
class Value{
};
Value<Option::B> b;
Value<static_cast<Option>(2)> c;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.