简体   繁体   中英

non-type template parameter alias in a different type

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM