【问题标题】:Return object of certain class from vector of objects从对象向量返回某个类的对象
【发布时间】:2020-05-20 15:29:26
【问题描述】:

我需要一个函数来从另一个类的组件数组中找到一个类类型的组件。

此功能不起作用,使用时会给出“类型名称不允许”...

template<typename T> auto* GetComponent(T& comp)
{
    for (int i = 0; i < Components.size(); ++i)
    {
        if (static_cast<T*>(Components.at(i))) return Components.at(i);
    }

}

【问题讨论】:

  • (1) 错误消息包含更多的文本。不用转述,直接复制全文。 (2) 即使修复了该错误,从长远来看,此函数也不会执行您想要的操作,因为static_cast 不会进行运行时类型检查(我假设您想要 check i> 对象的类型正确)。
  • 那么如何从基类的向量中获取指定派生类的对象呢?
  • dynamic_cast 似乎比static_cast 更合适。

标签: c++ object vector


【解决方案1】:

这是一个使用 dynamic_cast 而不是 static_cast 的示例,正​​如 Jarod42 所建议的那样。两个模板,For 对每个匹配类型执行一个仿函数,GetComponent 更接近问题中提供的代码 sn-p。

#include <iostream>
#include <memory>
#include <vector>

namespace {

struct Animal { virtual ~Animal(); };

Animal::~Animal() = default;

struct Horse : Animal { };

struct Dog : Animal { };

struct Zebra : Animal { };

struct Cow : Animal {
    std::string noise;
    Cow(std::string noise_) : noise{std::move(noise_)} { }
    void print(std::ostream&) const;
};

void Cow::print(std::ostream& out) const {
    out << "Cow says " << noise << "\n";
}

template <typename T, typename C, typename F>
void For(C const& container, F fn) {
    for (auto const& item : container) {
        auto p = dynamic_cast<T const*>(item);
        if (p != nullptr) fn(*p);
    }
}

template<typename T, typename C> auto* GetComponent(C const& container) {
    for (auto const& item : container) {
        auto p = dynamic_cast<T const*>(item);
        if (p != nullptr) return p;
    }

    return static_cast<T const*>(nullptr);
}


} // anon

int main() {
    Horse horse;
    Cow cow1{"moo"};
    Dog dog;
    Cow cow2{"snort"};

    std::vector<Animal*> v;
    v.push_back(&horse);
    v.push_back(&cow1);
    v.push_back(&dog);
    v.push_back(&cow2);

    For<Cow>(v, [](Cow const& cow) { cow.print(std::cout); });

    auto first_cow = GetComponent<Cow>(v);
    std::cout << "first cow:";

    if (first_cow) first_cow->print(std::cout);
    else std::cout << "(null)\n";

    auto first_dog = GetComponent<Dog>(v);
    std::cout << "first dog:" << (first_dog ? "yes" : "(null)") << "\n";

    auto first_zebra = GetComponent<Zebra>(v);
    std::cout << "first zebra:" << (first_zebra ? "yes" : "(null)") << "\n";
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-01-04
    • 2011-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-15
    相关资源
    最近更新 更多