std :: карта строки для увеличения :: thread_specific_ptr

Почему не удается скомпилировать g ++ 4.6 и g ++ 4.7?
Я пытаюсь получить сопоставление строки в конкретном потоке памяти.
Я думаю, что у меня было что-то подобное в надстройке 1.48.
На самом деле, это не связано с версией boost, но с флагом -std = c ++ 0x.
Если этого нет, он компилируется. Итак, ищем интерпретацию ошибки и
как обойти это.

Спасибо

#include <map>
#include <boost/thread/tss.hpp>
#include <boost/shared_ptr.hpp>

int main(int argc, char** argv) {
typedef boost::thread_specific_ptr< int > Tss_int_ptr;
typedef std::map< std::string, Tss_int_ptr > Tss_int_map_t;
Tss_int_map_t tmap;
return 0;
}

Сообщение об ошибке следует.

g++-4.7 -g -std=c++0x -I"/home/someone/open_source/admin/install/boost_1_52_0/include" -c  ~/tmp/fail.cpp
In file included from /usr/include/c++/4.7/bits/stl_algobase.h:65:0,
from /usr/include/c++/4.7/bits/stl_tree.h:63,
from /usr/include/c++/4.7/map:60,
from /home/someone/tmp/fail.cpp:1:
/usr/include/c++/4.7/bits/stl_pair.h: In instantiation of ‘struct std::pair<const std::basic_string<char>, boost::thread_specific_ptr<int> >’:
/usr/include/c++/4.7/bits/stl_tree.h:133:12:   required from ‘struct std::_Rb_tree_node<std::pair<const std::basic_string<char>, boost::thread_specific_ptr<int> > >’
/usr/include/c++/4.7/bits/stl_tree.h:1082:4:   required from ‘void std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_erase(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type) [with _Key = std::basic_string<char>; _Val = std::pair<const std::basic_string<char>, boost::thread_specific_ptr<int> >; _KeyOfValue = std::_Select1st<std::pair<const std::basic_string<char>, boost::thread_specific_ptr<int> > >; _Compare = std::less<std::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::basic_string<char>, boost::thread_specific_ptr<int> > >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type = std::_Rb_tree_node<std::pair<const std::basic_string<char>, boost::thread_specific_ptr<int> > >*]’
/usr/include/c++/4.7/bits/stl_tree.h:646:9:   required from ‘std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::~_Rb_tree() [with _Key = std::basic_string<char>; _Val = std::pair<const std::basic_string<char>, boost::thread_specific_ptr<int> >; _KeyOfValue = std::_Select1st<std::pair<const std::basic_string<char>, boost::thread_specific_ptr<int> > >; _Compare = std::less<std::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::basic_string<char>, boost::thread_specific_ptr<int> > >]’
/usr/include/c++/4.7/bits/stl_map.h:90:11:   required from here
/usr/include/c++/4.7/bits/stl_pair.h:119:17: error: ‘constexpr std::pair<_T1, _T2>::pair(const std::pair<_T1, _T2>&) [with _T1 = const std::basic_string<char>; _T2 = boost::thread_specific_ptr<int>; std::pair<_T1, _T2> = std::pair<const std::basic_string<char>, boost::thread_specific_ptr<int> >]’ declared to take const reference, but implicit declaration would take non-const

3

Решение

thread_specific_ptr объявляет эти члены, чтобы сделать класс не копируемым (обратите внимание на неконстантные параметры):

private:
thread_specific_ptr(thread_specific_ptr&);
thread_specific_ptr& operator=(thread_specific_ptr&);

В С ++ 03 std::pair не имеет объявленного конструктора копирования, поэтому он создается неявно, если это необходимо для программы. std::pair<X, thread_specific_ptr> не подлежит копированию, поскольку один из его членов не подлежит копированию, поэтому, если использовался неявный конструктор копирования, это было бы ошибкой.

В С ++ 11 std::pair имеет конструктор копирования, который явно по умолчанию. Имеет подпись:

pair(const pair&) = default;

Ошибка компилятора говорит вам, что неявно сгенерированный конструктор копирования будет иметь эту подпись, потому что thread_specific_ptr Копия конструктора подписи принимает неконстантную ссылку:

pair(pair&) = default;

Поскольку конструктор по умолчанию не имеет той же сигнатуры, которая была бы объявлена ​​неявно, конструктор копирования неверно сформирован.

Так что в обоих случаях pair<X, thread_specific_ptr> не копируется, но в C ++ 11 ошибка замечена раньше, даже если вы не пытаетесь скопировать объект.

Если boost::thread_specific_ptr использовал обычную идиому C ++ 11 для того, чтобы сделать класс не копируемым, код будет работать:

thread_specific_ptr(const thread_specific_ptr&) = delete;
thread_specific_ptr& operator=(const thread_specific_ptr&) = delete;

Так что я бы сообщил об этом как об ошибке в Boost. В режиме C ++ 11 операции копирования должны быть удалены.

В качестве обходного пути вы можете обернуть тип в свой собственный тип удаленными операциями копирования, а затем использовать его вместо этого:

template<typename T>
struct TSS : boost::thread_specific_ptr<T>
{
TSS() = default;
TSS(void (*f)(T*)) : boost::thread_specific_ptr<T>(f) { }
TSS(const TSS&) = delete;
TSS& operator=(const TSS&) = delete;
};

Теперь вы можете использовать это, и ваш код будет компилироваться:

typedef TSS< int > Tss_int_ptr;
5

Другие решения

Boost::thread-specific_ptr класс не копируется в некоторых версиях буста, что означает его нельзя использовать в контейнерах c ++ 03 STL. Я предполагаю, что это корень проблемы, и почему изменение флагов c ++ 0x исправляет это.

2

По вопросам рекламы [email protected]