问题
Compile time expressions are good because you can use them to specialize templates. So for example, tuples can be accessed by using a compile time expression with the std::get
method.
std::cout << std::get<0>(my_tuple) << std::endl;
Now, the above expression is pretty ugly. I am trying to develop some sort of tuples myself (hoping to make it to turn them into compile time dictionaries), so that, say, they expose a method in the form:
my_dict.get<0>();
Now, what I would like to do is to substitute that with a [] operator. I was wondering if that was even possible at all. First of all, I wouldn't know how to select only constant, compile time known expressions as parameters for my operator. Moreover, the return type would depend on the value of the constant expression.
With a define, however, I can get closer to what I want with something like
#define item(x) get<x>()
so that I can then use
my_dict.item(0)
Is there a way to get something better than this?
回答1:
This approach uses types to convey the index, which are then passed to operator[]
, which extracts the index.
template<std::size_t n>
using idx_t=std::integral_constant<std::size_t, n>;
template<std::size_t n>
idx_t<n> idx;
constexpr int square( int x ) { return x*x; }
constexpr int power( int base, size_t pow ) {
return (pow==0)?1:
(pow==1)?base:
(
square(power(base, pow/2))
*( (pow%2)?base:1 )
);
}
template<char... cs>
struct helper:idx_t<0>{};
template<char c0, char...cs>
struct helper<c0, cs...>:idx_t< (c0-'0') * power(10, sizeof...(cs)) + helper<cs...>{} > {};
template<char...cs>
constexpr idx_t< helper<cs...>{} > operator""_idx() { return {}; }
struct foo {
template<std::size_t n>
void operator[](idx_t<n>) const {
char arr[n];
std::cout << sizeof(arr) << '\n';
}
};
There are 3 (equivalent, up to syntactic sugar) ways to use this:
foo f;
f[idx_t<1>{}];
f[idx<2>];
f[3_idx];
f[1337_idx];
live example. Support for 0xff_idx
etc is left as an exercise.
来源:https://stackoverflow.com/questions/30549431/a-function-that-accepts-only-compile-time-known-expressions