2012-04-17 6 views
4

Каков рекомендуемый способ преобразования строки в массив? Я ищу что-то вроде:Std :: string to std :: array?

template<class T, size_t N, class V> 
std::array<T, N> to_array(const V& v) 
{ 
    assert(v.size() == N); 
    std::array<T, N> d; 
    std::copy(v.begin(), v.end(), d.data()); 
    return d; 
} 

Предоставляет ли C++ 11 или Boost что-то вроде этого? Как это делают другие? Кажется глупым копировать/вставлять эту функцию каждый раз, когда мне это нужно в проекте.

+5

Эмм, положите его в заголовок? –

+0

И вам это нужно ...? –

+0

У меня есть карта с примерно 1 миллионом 20 (или 32) байтовых ключей, и я бы хотел избежать дополнительных распределений и указаний, необходимых для std :: string – XTF

ответ

4

Это похоже. В C++ 11 такого не бывает, и я не думаю, что в Boost тоже есть. Если вы не хотите вставлять это по всему месту, вы можете просто поместить его в заголовок и #include.

+0

Копирование заголовка немного лучше, чем копирование функции, но все же не идеально подходит для чего-то основного, как для построения массива , – XTF

+3

Вам нужно это в * каждом проекте? Это поражает меня как нечто, имеющее конкретную нишу. И именно поэтому вы не находите его в C++ 11 или boost: это не очень простая вещь. –

+3

Обычно, когда у вас есть серия проектов в компании, вы помещаете их в одну иерархию иерархических каталогов с общими библиотеками. Профессионалы не копируют файлы из boost, которые они хотят использовать для каждого проекта, используя их; у них есть один экземпляр повышения и использовать его из одного места в своих проектах. Аналогично, если у вас есть заголовок библиотеки утилиты с этой функцией, вы не копируете его в каждый проект, вы используете один заголовок в специальном месте. Таким образом, если вам нужно исправить функцию или обновление, вы не будете разбираться с расхождением кода и bugfix несколько раз. – ex0du5

0

Если вы действительно хотите только конвертировать строку в массив, просто использовать .c_str() (и работать на char*). Это не точно array<>, но может удовлетворить ваши потребности.

+1

Нет, это не соответствует моим потребностям, так как это ссылка, в то время как мне нужно значение. – XTF

+0

Почему бы не сделать копию? –

+0

Вот что я делаю ... – XTF

1

Это нормально, возможно, с незначительной модификацией в C++ 11.

template<class T, size_t N, class V> 
std::array<T, N> to_array(const V& v) 
{ 
    assert(v.size() == N); 
    std::array<T, N> d; 
    using std::begin; using std::end; 
    std::copy(begin(v), end(v), begin(d)); // this is the recommended way 
    return d; 
} 

Таким образом, если вы удалите это утверждение, эта функция будет работать, даже если v является необработанным массивом.

+0

Это C++ 11. В этом случае может быть хорошо. Вы уверены, что это std :: begin(), а не только begin()? Ваш код не будет работать для классов, у которых есть свободное начало() в собственном пространстве имен. – XTF

+3

Возможно, следует использовать 'std :: begin; используя std :: end; std :: copy (begin (v), end (v), begin (d)); ' – bames53

+0

@XTF, который не был той версией, которую я написал, я не помещал пространство имен из-за поиска имени, которое должно работать в любом случае. Однако я считаю, что предложение bames53 делает его полностью общим, используя std one, когда он является контейнером std и конкретным, когда он не является (если найден). – Klaim

1

Просто позвонив:

std::copy(v.begin(), v.end(), d.data()); 

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

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

Смежные вопросы