首页 > 解决方案 > Generic polymorphism: create a variable of whatever type and use it

问题描述

I believe this is also called "type erasure". Consider the following not too minimal and not working code example:

#include <string>
#include <tuple>


std::pair<int, int> foo(int);
std::pair<std::string, std::string> foo(std::string);


struct S
{
    S(int);
    S(std::string);
};



int main()
{
    const auto some_bool{ false };

    const auto data =
    [ some_bool ]
    ()
    {
        if(some_bool)
        {
            return foo(42);
        }
        else
        {
             return foo("fourty-two");  // error: different return type
        }
    }
    ();

    const auto s{ data.first };

    // use s and data.second regardless of it's type
}

I would like to:

What would be a nice approach?

标签: c++generics

解决方案


为了能够使用.firstand .secondon data,您将需要一对两个类型擦除的值,因为您需要避免擦除它是一对的事实。IEstd::pair<erased_type, erased_type>

在您的示例中,您提前知道类型列表,因此您应该使用std::variant<>创建一个可以包含已知替代方案之一的类型。如果您在编译时不知道该列表,则可以使用std::any

using int_or_string = std::variant<int, std::string>;
using data_type = std::pair<int_or_string, int_or_string>;

接下来,您可以强制 lambda 返回此擦除的类型,并让各种返回值隐式转换为它:

[...]
    using int_or_string = std::variant<int, std::string>;
    const auto data =
    [ some_bool ]
    () -> std::pair<int_or_string, int_or_string>
    {
[...]

推荐阅读