C++(3364):应用运算符->或->* 而不是指针类型

exdqitrt  于 2023-03-20  发布在  其他
关注(0)|答案(1)|浏览(826)

我已经声明并填充了一个Map:std::map<std::string, std::vector<std::pair<std::string, std::vector<std::vector<float>>>>> data; .
我有一个打印功能来打印Map的内容,如下所示:

void print() {
    for (auto it : data) {
        std::cout << it->first << "\n";
        for (auto iter : it->second) {
            std::cout << iter->first << "\n";
            for (auto val : iter->second) {
                std::cout << val->second << "";
            }
            std::cout << "\n";
        }
        std::cout << "\n";
    }
}

但是,当我编译程序时,我得到了以下错误:

operator -> or ->* applied to "std::pair<const std::string,
std::vector<std::pair<std::string,
std::vector<std::vector<float, 
std::allocator<float>>, 
std::allocator<std::vector<float, std::allocator<float>>>>>, 
std::allocator<std::pair<std::string, 
std::vector<std::vector<float, std::allocator<float>>, 
std::allocator<std::vector<float, std::allocator<float>>>>>>>>" 
instead of to a pointer typeC/C++(3364)

我不知道我做错了什么。
我还尝试通过(*it).first访问Map数据,这会引发以下错误:

no operator "*" matches these operandsC/C++(349)
myfile.cpp(80, 23): operand types are: * std::pair<const std::string, 
std::vector<std::pair<std::string, std::vector<std::vector<float, 
std::allocator<float>>, std::allocator<std::vector<float, 
std::allocator<float>>>>>, std::allocator<std::pair<std::string, 
std::vector<std::vector<float, std::allocator<float>>, 
std::allocator<std::vector<float, std::allocator<float>>>>>>>>

我应该做什么而不是我已经做了什么?请让我知道,如果我错了代码的任何地方。

plicqrtu

plicqrtu1#

当你试图展开你的Map时,你犯了几个错误。你需要从外部结构到内部结构。
您需要理解,使用基于范围的for循环已经展开了一个级别。
为了学习它,您应该避免使用auto关键字,因为这样您 * 必须 * 命名正确的数据类型。
所有上述情况将导致:

#include <iostream>
#include <vector>
#include <map>
#include <utility>
using namespace std::string_literals;

std::map<std::string, std::vector<std::pair<std::string, std::vector<std::vector<float>>>>> data{
    {"OuterMapS1"s, {  {"v1PairLeft1"s, {{1.1f,2.2f},{3.3f,4.4f}}},{"v2PairLeft2"s, {{5.5f,6.6f,7.7f},{1.2f,1.3f}}}}},
    {"OuterMapS2"s, {  {"v3PairLeft3"s, {{7.0f,8.0f,9.0f},{3.5f,4.6f}}},{"v4PairLeft4"s, {{3.5f,3.6f,3.7f},{4.2f,4.3f,4.4f}}}}}
};

int main() {
    for (const std::pair<const std::string,std::vector<std::pair<std::string,std::vector<std::vector<float>>>>>& p1 : data) {
        std::cout << p1.first << '\n';
        for (const std::pair<std::string, std::vector<std::vector<float>>>& p2 : p1.second) {
            std::cout << '\t' << p2.first << '\n';
            for (const std::vector<float> &vOuter : p2.second) { 
                std::cout << "\t\t\t";
                for (const float& f : vOuter) {
                    std::cout << f << '\t';
                }
                std::cout << '\n';
            }
        }
        std::cout << '\n';
    }
}

另外,用using语句定义自己的类型也会很有帮助。然后,你可以先从内到外构建你的数据结构。为了打印,你可以使用预定义的类型。
这会让生活变得简单一点:

#include <iostream>
#include <vector>
#include <map>
#include <utility>
using namespace std::string_literals;

using FloatVec = std::vector<float>;
using Float2dVec = std::vector<FloatVec>;
using PairStr2dFloatVec = std::pair<std::string, Float2dVec>;
using VecPairStr2dFloatVec = std::vector<PairStr2dFloatVec>;
using MyMap = std::map<std::string, VecPairStr2dFloatVec>;
using MyMapPair = MyMap::value_type;

MyMap data{
    {"OuterMapS1"s, {  {"v1PairLeft1"s, {{1.1f,2.2f},{3.3f,4.4f}}},{"v2PairLeft2"s, {{5.5f,6.6f,7.7f},{1.2f,1.3f}}}}},
    {"OuterMapS2"s, {  {"v3PairLeft3"s, {{7.0f,8.0f,9.0f},{3.5f,4.6f}}},{"v4PairLeft4"s, {{3.5f,3.6f,3.7f},{4.2f,4.3f,4.4f}}}}}
};

int main() {
    for (const MyMapPair& p1 : data) {
        std::cout << p1.first << '\n';
        for (const PairStr2dFloatVec& p2 : p1.second) {
            std::cout << '\t' << p2.first << '\n';
            for (const FloatVec& vOuter : p2.second) {
                std::cout << "\t\t\t";
                for (const float& f : vOuter) {
                    std::cout << f << '\t';
                }
                std::cout << '\n';
            }
        }
        std::cout << '\n';
    }
}

最后但并非最不重要的一点是,您可以对std::mapstd::pair使用结构化绑定,这一次还是使用auto,但同样更具可读性:

#include <iostream>
#include <vector>
#include <map>
#include <utility>
using namespace std::string_literals;

using FloatVec = std::vector<float>;
using Float2dVec = std::vector<FloatVec>;
using PairStr2dFloatVec = std::pair<std::string, Float2dVec>;
using VecPairStr2dFloatVec = std::vector<PairStr2dFloatVec>;
using MyMap = std::map<std::string, VecPairStr2dFloatVec>;
using MyMapPair = MyMap::value_type;

MyMap data{
    {"OuterMapS1"s, {  {"v1PairLeft1"s, {{1.1f,2.2f},{3.3f,4.4f}}},{"v2PairLeft2"s, {{5.5f,6.6f,7.7f},{1.2f,1.3f}}}}},
    {"OuterMapS2"s, {  {"v3PairLeft3"s, {{7.0f,8.0f,9.0f},{3.5f,4.6f}}},{"v4PairLeft4"s, {{3.5f,3.6f,3.7f},{4.2f,4.3f,4.4f}}}}}
};

int main() {
    for (const auto& [outerString, outerVector] : data) {
        std::cout << outerString << '\n';
        for (const auto& [innerString, nextVector] : outerVector) {
            std::cout << '\t' << innerString << '\n';
            for (const FloatVec& fVector : nextVector) {
                std::cout << "\t\t\t";
                for (const float& f : fVector) {
                    std::cout << f << '\t';
                }
                std::cout << '\n';
            }
        }
        std::cout << '\n';
    }
}

不幸的是,复杂的数据结构将使访问子元素有点困难。

相关问题