C++:是否可以使用指向向量的“通用”指针?

C++: is it possible to use "universal" pointer to vector?

提问人:Damian L 提问时间:10/26/2022 最后编辑:YksisarvinenDamian L 更新时间:10/26/2022 访问量:85

问:

美好的一天,SO 社区! 我是C++的新手,在我的项目中遇到了一种情况,我有2个相似配对数据类型的向量:

std::vector<std::pair<int, std::string> firstDataVector
std::vector<std::pair<int, std::string> secondDataVector

在代码的一部分中,我需要根据外部字符串值选择和处理向量。所以我的问题是 - 是否可以在条件之外创建一个指向向量的指针

if (stringValue.find("firstStringCondition"))
{
    //use firstDataVector
}
if (stringValue.find("secondStringCondition"))
{
    //use secondDataVector
}

某种 pDataVector 指针,可以将现有向量分配给该指针(因为现在项目只有两个,但向量计数可能会增加)

我尝试创建指针,但它不起作用,因为必须初始化引用变量。所以总结一下问题 - 是否有可能有指向向量的通用指针?std::vector<std::string> &pDataVector

C++ 矢量 标准

评论

2赞 molbdnilo 10/26/2022
这是一个参考,而不是一个指针。指针类型拼写为 。指向向量的指针与所有其他(对象)指针完全相同;如果 是 ,则为 .*xT&xT*
0赞 Yksisarvinen 10/26/2022
firstDataVector并且属于同一类型,据我们所知,不是“相似”类型。首先想到的是将“use XVector”提取到一个函数中,然后用正确的参数调用它,而无需创建单独的指针。secondDataVector
0赞 Pepijn Kramer 10/26/2022
制作一个映射 std::map<std::string, std::vector<std::p air<int, std::string>>然后你可以根据名称查找正确的 std::vector<std::p air<int, std::string>...
0赞 NathanOliver 10/26/2022
使用一个怎么样?std::vector<std::pair<int, std::string>::iterartor
0赞 Ted Lyngmo 10/26/2022
如果两者都找不到匹配项怎么办?find

答:

2赞 Ted Lyngmo 10/26/2022 #1

您正在尝试创建对其中一个 s 的引用 - 这当然是可能的,但必须对其进行初始化才能引用它。你不能推迟它。vector

如果没有找到匹配项,目前尚不清楚您希望发生什么,因此我选择抛出异常。stringValue

现在项目只有两个,但向量计数可能会增加

  • 创建一个在要尝试的字符串之间映射,然后创建要创建的引用。vectorfindstringValuevector
  • 初始化时,您可以调用返回引用的函子,如 lambda。pDataVector
  • 在函数中,循环使用您要尝试的字符串,并返回您获得的第一个匹配项的引用。vectorfindvector

它可能看起来像这样:

#include <functional>
#include <iostream>
#include <string>
#include <vector>

int main() {
    using vpstype = std::vector<std::pair<int, std::string>>;

    vpstype firstDataVector{{1, "Hello"}};
    vpstype secondDataVector{{2, "World"}};

    // A vector of the condition strings you want to check keeping the order
    // in which you want to check them.
    std::vector<std::pair<std::string, std::reference_wrapper<vpstype>>>
        conditions{
            {"firstStringCondition", firstDataVector},
            {"secondStringCondition", secondDataVector},
            // add more mappings here
        };

    // an example stringValue
    std::string stringValue = "ssdfdfsdfsecondStringConditionsdfsfsdf";

    // initialize the vpstype reference:
    auto& pDataVector = [&]() -> vpstype& {
        // loop over all the strings and referenced vpstypes:
        for (auto& [cond, vps] : conditions) {
            if (stringValue.find(cond) != std::string::npos) return vps;
        }
        throw std::runtime_error("stringValue doesn't match any condition string");
    }();

    // and use the result:
    for (auto [i, s] : pDataVector) {
        std::cout << i << ' ' << s << '\n'; // prints "2 world"
    }
}

评论

1赞 Damian L 10/27/2022
这个对我有用!谢谢大家,感谢大家的精彩回答!
0赞 Sven Nilsson 10/26/2022 #2

您确实可以有条件地初始化引用。使用返回要引用的向量的函数或 lambda,或对其进行硬编码,如下所示。

std::vector<std::string> &pDataVector = 
    (stringValue.find("firstStringCondition") != std::string::npos) ?
        firstDataVector : ((stringValue.find("secondStringCondition") != std::string::npos) ?
            secondDataVector : thirdDataVector);

评论

0赞 Ted Lyngmo 10/26/2022
考虑到“现在项目只有两个,但向量数量可能会增加”,这很快就会变得不切实际 - 但可以肯定的是,对于两个来说,它是有效的!
1赞 Sven Nilsson 10/26/2022
谢谢,我什至没有意识到这是一个 std::string,所以我从 OP 中复制了错误。