是否可以将STL multimap value_type函数与多参数C ++构造函数一起使用

时间:2011-06-06 14:20:35

标签: c++ linux stl

早上好,在Scott Meyers的书“Effective STL”中,Meyers先生解释了map :: value_type函数如何节省构造和删除临时对象的成本。     我们正在尝试使用Mr. Meyers技术和多图,其中类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函数,以便我们可以使用Mr. Meyers技术?谢谢。

2 个答案:

答案 0 :(得分:1)

第三个选项在支持C ++ 0x的编译器中以emplace形式提供,如gcc 4.5或4.6。

目前std :: pair只能用两个参数构造。变量模板将改变它并提供新的可能性,rvalue引用和完美转发也是如此。

答案 1 :(得分:1)

好的,让我们稍微简化一下: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同时期望KeyValue,但您提供了Key和一些垃圾。

你必须调用Range的构造函数,然后希望复制Elision才能启动。很可能会这样。