2015-05-30 1 views
6

Сроки выражения компиляции хороши, потому что вы можете использовать их для специализирования шаблонов. Так, например, кортежи можно получить, используя выражение времени компиляции с помощью метода std::get.Функция, которая принимает только известные выражения времени компиляции?

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

Теперь вышеназванное выражение довольно уродливое. Я пытаюсь разработать какую-то кортежей себя (в надежде сделать это, чтобы превратить их в компиляции словарей время), так что, скажем, они выставляют метод в форме:

my_dict.get<0>(); 

Теперь, что я хотел сделать это, чтобы заменить это на оператор []. Мне было интересно, возможно ли это вообще. Прежде всего, я бы не знал, как выбирать только константы, компилировать известные временем выражения как параметры для моего оператора. Более того, тип возврата будет зависеть от значения константного выражения.

С определить, однако, я могу стать ближе к тому, что я хочу что-то вроде

#define item(x) get<x>() 

, так что я могу затем использовать

my_dict.item(0) 

Есть ли способ, чтобы получить что-то лучше, чем это?

+9

Я не понимаю вашу цель, вообще. Примите аргумент только как аргумент шаблона. Проблема решена ... –

+2

Пользовательские литералы, которые легко определяют объекты 'std :: integral_constant'? http://coliru.stacked-crooked.com/a/f8450185699979be – dyp

+0

@LightnessRacesinOrbit: вы не можете полностью превратить аргумент 'operator []' в аргумент шаблона. – doublep

ответ

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 и т. Д. Оставлена ​​в качестве упражнения.