Можно ли использовать функцию STL multimap value_type с конструктором C ++ с несколькими аргументами - PullRequest
0 голосов
/ 06 июня 2011

Доброе утро, в книге Скотта Мейерса Effective STL Мистер Мейерс объясняет, как функция map :: value_type экономит затраты на создание и удаление временного объекта.Мы пытаемся использовать технику мистера Мейерса с мультикартой, где класс Range имеет два конструктора:

class Range { 
     public:   
         explicit Range(int item){ 
                .....
         }
         Range(int low, int high, char* ptr = 0,char* mapptr = 0, int stamp = 0, 
               int casenumber = 100, int currN = 0){  
            .......     
         }
};

Компилятор Linux g ++ жалуется, когда мы пробуем следующий код:

void cMemoryMappedFile::AddFinalRange(int CurrN)
{
    typedef std::multiset<Range> RangeMultiSet;
    typedef std::multimap<char*, Range> RangeMultiMap;
    // OK with g++ 4.1.2 Compiler
    ranges_type.insert(RangeMultiSet::value_type(PreviousN,FileSize,
        &prevadjustedptr[PreviousN],MapPtr,TimeStamp + 1,0,CurrN));

    // OK with g++ 4.1.2 Compiler
    mmultimap.insert(std::make_pair(MapPtr,
        Range(PreviousN,FileSize,&prevadjustedptr[PreviousN],
        MapPtr,TimeStamp +  1,0,CurrN)));


    // Not OK with g++ 4.1.2 Compiler
    mmultimap.insert(RangeMultiMap::value_type((char* const)MapPtr,
        PreviousN,FileSize,&prevadjustedptr[PreviousN],
        MapPtr,TimeStamp + 1,0,CurrN));
}

Ошибка компилятора G ++ 4.1.2 заключается в следующем:

g++ -g -Wall -W -Wno-unused -Wno-sign-compare -D_DEBUG -pthread -DTHREADSAFE -m32 
-D_NO_GUI -DDTAPI -DNO_LOOKUP_DBF -DNO_ASCII -DCONFIG_SECURITY  
-I../Include -I../../cpswindows/Include -I../../sqlite 
-I../../util -I../../zlib -I../../str 
-I/home/frankc/DQTTest2/valgrind-3.6.1/callgrind -I/home/frankc/DQTTest2/valgrind-3.6.1/include 
-fpic ../Source/cMemoryMappedFile.cpp -o cMemoryMappedFile.o -c
../Source/cMemoryMappedFile.cpp: In member function ‘void cMemoryMappedFile::AddFinalRange(int)’:
../Source/cMemoryMappedFile.cpp:663: 
error: no matching function for call to 
std::pair<char* const, Range>::pair(char* const, unsigned int&, long int&, char*, char*&, 
int, int, int&)’
/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_pair.h:84: 
note: candidates are: std::pair<_T1, _T2>::pair(const _T1&, const _T2&) 
[with _T1 = char* const, _T2 = Range]
/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_pair.h:80: note: 
                std::pair<_T1, _T2>::pair() [with _T1 = char* const, _T2 = Range]
/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_pair.h:69: note: 
                std::pair<char* const, Range>::pair(const std::pair<char* const, Range>&)

Нам было интересно, можно ли исправить эту ошибку компилятора, чтобы мы могли использовать функцию multimap :: value_type, чтобы мы могли использовать метод мистера Мейерса?Спасибо.

Ответы [ 2 ]

1 голос
/ 06 июня 2011

Хорошо, давайте немного упростим это: p?

// OK with g++ 4.1.2 Compiler
mmultimap.insert(std::make_pair(MapPtr,
    Range(PreviousN,FileSize,&prevadjustedptr[PreviousN],
    MapPtr,TimeStamp +  1,0,CurrN)));


// Not OK with g++ 4.1.2 Compiler
mmultimap.insert(RangeMultiMap::value_type((char* const)MapPtr,
    PreviousN,FileSize,&prevadjustedptr[PreviousN],
    MapPtr,TimeStamp + 1,0,CurrN));

Фактически похоже на:

// OK with g++ 4.1.2 Compiler
mmultimap.insert(std::make_pair(MapPtr, Range(0)));


// Not OK with g++ 4.1.2 Compiler
mmultimap.insert(RangeMultiMap::value_type(MapPtr, 0));

Примечание:

  • Актерский состав совершенно не нужен
  • конструктор Range равен explicit и поэтому не будет называться

Проблема здесь в том, что value_type ожидают и Key, и Value, но вы предоставляете Key и немного мусора.

Вы должны вызвать конструктор Range и надеяться , чтобы Copy Elision заработала. Вероятно, что так и будет.

1 голос
/ 06 июня 2011

Третий параметр будет доступен как emplace в компиляторе, поддерживающем C ++ 0x, например, gcc 4.5 или 4.6.

В настоящее время std :: pair может быть создан только с двумя параметрами.Шаблоны Variadic изменят это и предложат новые возможности, а также оценят ссылки и совершенную пересылку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...