一个只接受编译时已知表达式的函数?

时间:2015-05-30 17:51:29

标签: c++ templates operators compile-time-constant

编译时表达式很好,因为您可以使用它们来专门化模板。因此,例如,可以使用带有std::get方法的编译时表达式来访问元组。

std::cout << std::get<0>(my_tuple) << std::endl;

现在,上面的表达非常难看。我正在尝试自己开发某种元组(希望将它转换为编译时字典),这样,他们就会在表单中公开一个方法:

my_dict.get<0>();

现在,我想做的是用[]运算符替换它。我想知道这是否甚至可能。首先,我不知道如何只选择常量,编译时已知表达式作为我的运算符的参数。而且,返回类型将取决于常量表达式的值。

然而,通过定义,我可以通过

之类的东西更接近我想要的东西
#define item(x) get<x>()

以便我可以使用

my_dict.item(0)

有没有办法让事情比这更好?

1 个答案:

答案 0 :(得分:2)

此方法使用类型来传达索引,然后将其传递给operator[],后者将提取索引。

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';
  }
};

有3种(相当于语法糖)的方法可以使用它:

foo f;
f[idx_t<1>{}];
f[idx<2>];
f[3_idx];
f[1337_idx];

live example。支持0xff_idx等作为练习。