2010-09-15 2 views
2

Я хотел бы передать числовые значения байтов через список инициализаторов вариационный шаблон в массив. Это возможно?Списки символов и инициализаторы

template < int N > struct a { 
    char s[N]; 
    template < typename ... A > 
    a (A ... _a) : s {_a...} {} 
}; 

int main() { 
    // g++-4.5: error: narrowing conversion of »_a#0« from »int« to »char« inside { } 
    a <3> x { 1, 2, 3 }; 
} 

То, что я могу думать о

  • использовать восьмеричное представление, '\ 001' и т.д., или
  • бросить каждое значение.

Но оба они не удовлетворяют.

+0

Почему это проблема бросить значения? Если вы хотите быть осторожным в том, что происходит, вы используете 'boost :: numeric_cast' и специально разрешаете сужение конверсий. Так или иначе, вы сужаете эти аргументы. – Potatoswatter

+0

Если вы не предоставляете конструктор, вы сможете использовать инициализацию скобок для агрегатов. – sellibitze

ответ

0

ПРИМЕЧАНИЕ: Все это не нужно, если вы не добавили функциональность класса, так что это уже не совокупность. (Например, другие конструкторы, частные члены, базовый класс и т. Д.). Прямой способ исправить код в вопросе - это просто удалить конструктор. Итак, давайте предположим, что есть что-то еще.

Я видел, как некоторые люди пытались это сделать. Кажется уродливым, имея дело с семантикой конверсии и попыткой искусственного воссоздания функциональности обычного вызова функции.

Вот стратегия создания класса массива, который в первую очередь имеет правый конструктор.

Наложение шаблона наложило глазурь на торт, спрятав ::type уродство, но оно еще не в GCC.

template< typename ... NT > 
struct var_ctor_array { 
    enum { size_e = 0 }; // only used for zero size case 
}; 

template< typename T, typename ... NT > 
struct var_ctor_array< T, NT ... > { 
    enum { size_e = 1 + sizeof...(NT) }; 

    T st[ size_e ]; 

    var_ctor_array(T elem0, NT ... elemN) 
     : st { elem0, elemN ... } {} 
}; 

template< typename T, size_t N, typename ... NT > 
struct gen_var_ctor_array { 
    typedef typename gen_var_ctor_array< T, N-1, T, NT ... >::type type; 
}; 

template< typename T, typename ... NT > 
struct gen_var_ctor_array< T, 0, NT ... > { 
    typedef var_ctor_array< NT ... > type; 
}; 

int main() { // usage 
    gen_var_ctor_array< char, 5 >::type five(1, 2, 3, 4, 5); 
} 
+0

Удивительная идея, я буду использовать классы. g ++ не будет компилироваться без специального случая для 'size_e == 0' из-за ошибки. Теперь, возможно ли иметь значение 'T()' как значение по умолчанию для каждого параметра? – Thomas

+0

@Thomas: Попытка: «Параметр pack« elemN »не может иметь аргумент по умолчанию». Однако эту функцию можно взломать с помощью наследующих конструкторов, которые не находятся в GCC 4.5. – Potatoswatter

+0

Что вызывает эту ошибку?'gen_var_ctor_array < char, 0 > :: type zero;' works ... – Potatoswatter

0

Вы фактически не используете списки инициализаторов. Конструктор получает variadic template, и вы инициализируете x с uniform initialization.

Единственная проблема, я не знаю элегантный способ инициализации массива с initializer_list, AFAIK std::array должен иметь конструктор, который принимает initializer_list, но это, кажется, не будет поддерживаться г ++ еще.

#include <utility> 
template < int N > struct a { 
    char s[N]; 

    a (std::initializer_list<char> list) { 
     if (N != list.size()) 
      throw "list wrong size"; 

     int i = 0; 
     const char* p = list.begin(); 
     while(p != list.end()) 
      s[i++] = *p++; 
    } 
}; 
+0

Вы абсолютно правы, вариационные шаблоны - это то, что я хотел написать. Списки инициализаторов, возможно, не так эффективны для инициализации массива. – Thomas

+0

'array' не нужно поддерживать' initializer_list', потому что он уже делает то же самое в C++ 03, будучи агрегатом. Ничто не является более эффективным, чем это, поскольку это эквивалентно инициализации на месте. – Potatoswatter

0

Вам не нужно никакого сложного кода

template < int N > struct a { 
    char s[N]; 
    template < typename ... A > 
    a (A ... _a) : s {static_cast<char>(_a)...} {} 
}; 
Смежные вопросы