C ++에서 문자열로 가득 찬 std :: map을 반복하는 방법
을 사용하여 정의 된 문자열의 연관 배열을 반복하는 것과 관련된 다음 문제가 있습니다 std::map
.
-- snip --
class something
{
//...
private:
std::map<std::string, std::string> table;
//...
}
생성자에서 문자열 데이터와 관련된 문자열 키 쌍으로 테이블을 채 웁니다. 다른 곳에서는 toString
테이블 개체 (키 = 데이터 형식)에 포함 된 모든 키와 관련 데이터를 포함하는 문자열 개체를 반환 하는 메서드 가 있습니다.
std::string something::toString()
{
std::map<std::string, std::string>::iterator iter;
std::string* strToReturn = new std::string("");
for (iter = table.begin(); iter != table.end(); iter++) {
strToReturn->append(iter->first());
strToReturn->append('=');
strToRetunr->append(iter->second());
//....
}
//...
}
컴파일하려고 할 때 다음 오류가 발생합니다.
error: "error: no match for call to ‘(std::basic_string<char,
std::char_traits<char>, std::allocator<char> >) ()’".
누군가 나에게 무엇이 빠졌는지, 내가 뭘 잘못하고 있는지 설명해 줄 수 있습니까? hash_map
사용자가 객체 hash_map
와 함께 사용할 수 있도록 해싱 함수를 정의해야하는 경우 유사한 문제에 대한 논의 만 찾았습니다 std::string
. 내 경우에도 비슷한 것이 될 수 있습니까?
주요 문제는 first()
반복기에서 호출되는 메서드를 호출한다는 것 입니다. 당신이하려는 것은 다음과 같은 속성을 사용하는 것입니다 first
.
...append(iter->first) rather than ...append(iter->first())
스타일의 문제로 new
해당 문자열을 만드는 데 사용해서는 안됩니다 .
std::string something::toString()
{
std::map<std::string, std::string>::iterator iter;
std::string strToReturn; //This is no longer on the heap
for (iter = table.begin(); iter != table.end(); ++iter) {
strToReturn.append(iter->first); //Not a method call
strToReturn.append("=");
strToReturn.append(iter->second);
//....
// Make sure you don't modify table here or the iterators will not work as you expect
}
//...
return strToReturn;
}
편집 : facildelembrar는 (주석에서) 현대 C ++에서 이제 루프를 다시 작성할 수 있다고 지적했습니다.
for (auto& item: table) {
...
}
toString()
메소드를 작성하지 마십시오 . 이것은 Java가 아닙니다. 클래스에 대한 스트림 연산자를 구현하십시오.자체 루프를 작성하는 것보다 표준 알고리즘을 사용하는 것이 좋습니다. 이 상황에서
std::for_each()
원하는 작업에 대한 멋진 인터페이스를 제공합니다.당신은 루프를 사용해야하지만, 데이터를 변경하지 않으려면, 선호
const_iterator
이상iterator
. 이렇게하면 실수로 값을 변경하려고하면 컴파일러에서 경고를 표시합니다.
그때:
std::ostream& operator<<(std::ostream& str,something const& data)
{
data.print(str)
return str;
}
void something::print(std::ostream& str) const
{
std::for_each(table.begin(),table.end(),PrintData(str));
}
Then when you want to print it, just stream the object:
int main()
{
something bob;
std::cout << bob;
}
If you actually need a string representation of the object, you can then use lexical_cast
.
int main()
{
something bob;
std::string rope = boost::lexical_cast<std::string>(bob);
}
The details that need to be filled in.
class somthing
{
typedef std::map<std::string,std::string> DataMap;
struct PrintData
{
PrintData(std::ostream& str): m_str(str) {}
void operator()(DataMap::value_type const& data) const
{
m_str << data.first << "=" << data.second << "\n";
}
private: std::ostream& m_str;
};
DataMap table;
public:
void something::print(std::ostream& str);
};
Change your append calls to say
...append(iter->first)
and
... append(iter->second)
Additionally, the line
std::string* strToReturn = new std::string("");
allocates a string on the heap. If you intend to actually return a pointer to this dynamically allocated string, the return should be changed to std::string*.
Alternatively, if you don't want to worry about managing that object on the heap, change the local declaration to
std::string strToReturn("");
and change the 'append' calls to use reference syntax...
strToReturn.append(...)
instead of
strToReturn->append(...)
Be aware that this will construct the string on the stack, then copy it into the return variable. This has performance implications.
Note that the result of dereferencing an std::map::iterator is an std::pair. The values of first
and second
are not functions, they are variables.
Change:
iter->first()
to
iter->first
Ditto with iter->second
.
iter->first
and iter->second
are variables, you are attempting to call them as methods.
Use:
std::map<std::string, std::string>::const_iterator
instead:
std::map<std::string, std::string>::iterator
in c++11 you can use
for ( auto iter : table ) {
key=iter->first();
value=iter->second();
}
Another worthy optimization is the c_str ( ) member of the STL string classes, which returns an immutable null terminated string that can be passed around as a LPCTSTR, e. g., to a custom function that expects a LPCTSTR. Although I haven't traced through the destructor to confirm it, I suspect that the string class looks after the memory in which it creates the copy.
참고URL : https://stackoverflow.com/questions/1066677/how-to-iterate-over-a-stdmap-full-of-strings-in-c
'programing tip' 카테고리의 다른 글
.NET 단위 테스트 패키지? (0) | 2020.11.28 |
---|---|
git-svn이 특정 svn 브랜치를 원격 저장소로 사용하게하려면 어떻게해야합니까? (0) | 2020.11.28 |
wpf 창에 사용자 정의 컨트롤 추가 (0) | 2020.11.28 |
경고-부호있는 정수 식과 부호없는 정수 식 비교 (0) | 2020.11.28 |
Windows에서 CMake 실행 (0) | 2020.11.28 |