我想获取存储在容器中的每个函数的返回类型。我试过 std::any 和 std::variant 但我想不通。详情如下:
#include <random>
#include <vector>
#include <functional>
using namespace std;
class Base
{
public: virtual void test() { }
};
class Derived1 : public Base
{
public: virtual void test() { }
};
class Derived2 : public Base
{
public: virtual void test() { }
};
int main ()
{
std::vector<std::function < Base(void)>> b;
b.push_back([&]() { return Derived1(); });
b.push_back([&]() { return Derived2(); });
b.push_back([&]() { return Base(); });
std::shuffle(b.begin(), b.end(), std::default_random_engine {});
for (auto fn : b)
{
// Here I would like to reach the derived classes from "fn" somehow and use it like "new Derived1"
//decltype(fn)::result_type ----------> this gives me Base only but i want the derived as well
}
}
fn
的类型是std::function<Base()>
,因此调用fn()
的结果总是一个Base
。那些 std::function
s 包装的 lambdas 返回其他类型并不重要。这些返回值用于初始化 Base
. 类型的对象
记住,在 C++ 中,多态性仅适用于引用和指针。虽然
Base&
或 Base*
可以指代 Derived1
对象,但 Base
对象不指代任何东西。它是一个Base
对象,它永远不可能是任何其他东西。
如果你想要多态性,你需要你的函数返回指针:
int main ()
{
std::vector<std::function<std::unique_ptr<Base>()>>> b;
b.push_back([&]() { return std::make_unique<Derived1>(); });
b.push_back([&]() { return std::make_unique<Derived2>(); });
b.push_back([&]() { return std::make_unique<Base>(); });
std::shuffle(b.begin(), b.end(), std::default_random_engine {});
for (auto fn : b)
{
fn()->test(); // Will call the correct overridden test
// depending on the runtime type of the
// object pointed to by the returned unique_ptr
}
}
我已经设法解决了这两种不同的方式。
第一种方式:
int main()
{
std::vector<std::function<Base& ()>> b;
b.push_back([]() -> Base& { static Derived1 d1; return d1; });
b.push_back([]() -> Base& { static Derived2 d2; return d2; });
b.push_back([]() -> Base& { static Base b; return b; });
std::shuffle(b.begin(), b.end(), std::default_random_engine{});
for (auto& fn : b)
{
if (auto derived2_ptr = dynamic_cast<Derived1*>(&fn()))
{
derived2_ptr->test();
Derived1* var = new Derived1(*derived2_ptr);
var->test();
}
else if (auto derived2_ptr = dynamic_cast<Derived2*>(&fn()))
{
derived2_ptr->test();
Derived2* var = new Derived2(*derived2_ptr);
var->test();
}
}
return 0;
}
第二种方式:
int main()
{
std::vector<std::function<std::shared_ptr<Base>()>> b;
b.push_back([&]() { return std::make_shared<Derived1>(); });
b.push_back([&]() { return std::make_shared<Derived2>(); });
b.push_back([&]() { return std::make_shared<Base>(); });
std::shuffle(b.begin(), b.end(), std::default_random_engine{});
for (auto fn : b)
{
if (auto derived1_ptr = std::dynamic_pointer_cast<Derived1>(fn()))
{
derived1_ptr->test();
shared_ptr<Derived1> var = std::make_shared<Derived1>(*derived1_ptr);
var->test();
}
else if (auto derived2_ptr = std::dynamic_pointer_cast<Derived2>(fn()))
{
derived2_ptr->test();
shared_ptr<Derived2> var = std::make_shared<Derived2>(*derived2_ptr);
var->test();
}
}
return 0;
}