首页 > 解决方案 > 如何构造一个 std::variant 类型对象,其自身模板化和构造函数转发参数

问题描述

我已经定义var_t为 type std::variant< Fum<Bazz>, Fum<Ack> >。模板化类Fum<>应该将其构造函数参数转发给 Bazz 和 Ack,以便它可以创建它们。但是,我收到以下错误:

[g++ default #1] error: no matching conversion for functional-style cast

Bazz 和 Ack 定义:

#include <iostream>
#include <variant>
#include <string>


// Bazz
// C'tor takes in float

struct Bazz {
    float f;

    Bazz(float)
    {
        std::cout << "Bazz Main" << std::endl;
    }

};

// Ack
// C'tor takes in std::string

struct Ack {
    std::string str;

    Ack(std::string strParam)
        :str(strParam)
    {
        std::cout << "Ack Main" << std::endl;

    }

};

定义:

// Fum<>
// Variadic C'Tor should forward args to value of type T

template<typename T>
class Fum {
public:
    T value;

    template<typename ... Params>
    Fum<T>(Params&& ... argsForT)
        :value(std::forward<Params>(argsForT)...)
    {std::cout << "FUM C'TOR" << std::endl;}
};

var_t 定义:

typedef std::variant< Fum<Bazz>, Fum<Ack> > var_t;

以下代码有效:

// Fum forwards string to Ack as expected and creates Ack emplace.
int main() {
    Fum<Ack>(std::string("Hello, World!"));
}

// >>>> Ack Main C'Tor
// >>>> Fum C'Tor

以下不起作用:

int main() {
    var_t((std::string("Hello, World!")));
}


// [g++ default #1] error: no matching conversion for functional- 
// style cast

我相信Fum模板化的 C'Tor 会引起歧义。因此, var_t 不知道它是否应该构造Fum<Ack>or Fum<Bazz>。但我不确定。那么我该如何解决这个问题呢?

标签: c++

解决方案


std::variant对emplace 建设有适当的超载。

尤其是:

template< class T, class... Args >
constexpr explicit variant(std::in_place_type_t<T>, Args&&... args);

因此,您的代码可以通过以下方式修复:

var_t(std::in_place_type<Fum<Ack>>, std::string("Hello, World!"));

推荐阅读