【问题标题】:Constrainted auto std::convertible_to with initializer list带有初始值设定项列表的约束 auto std::convertible_to
【发布时间】:2021-10-31 22:30:51
【问题描述】:

你好 stackoverflow 人,我最近正在尝试学习 c++20 约束 auto 作为函数参数,以减少样板代码。 我有一个类模板,它是一些数据类型的包装器,比如std::int64_t, bool, double, std::string,将来可能会添加更多,它有一个采用数据类型的函数和一个采用std::initializer_list<data_t> 数组的重载函数-操纵。

template<typename data_t>
void set_data(data_t a_data)

template<typename data_t>
void set_data(std::initializer_list<data_t> a_dataList)

如果我直接调用这些 setter 函数,这些都可以正常工作。

在管理所有这些数据的 api 类中,我有一个公开的 api,它基本上做同样的事情,我有这个:

template<typename data_t>
void bind(Wrapper<data_t>& a_data, const std::convertible_to<data_t> auto a_value)
{
    a_data.set_data(a_value);
}

template<typename data_t>
void bind(Wrapper<data_t>& a_data, const std::initializer_list<data_t> a_valueList)
{
    a_data.set_data(a_value);
}

第一个函数按预期工作,例如,我可以将任何可转换的数据类型传递给std::int64_t 的包装器,但是如果我想将初始化器列表传递给后者,我必须将类型显式转换为data_t像这样

Wrapper<std::int64_t> iA;

bind(iA, 100); // works
iA.set_data(100) // works

bind(iA, {1,2,3,4,5}); // no
iA.set_data({1,2,3,4,5}); // works
bind(iA, {(std::int64_t)1, (std::int64_t)2, (std::int64_t)3, (std::int64_t)4});
// works

所以我的问题终于出来了:我如何用std::initializer_list 实现类似std::convertible_to 的东西,这样我就不必像上面那样输入 cast 了?或者这完全可行?

【问题讨论】:

    标签: c++ c++20


    【解决方案1】:

    您的问题是 C++ 使用第一个和第二个参数推断 data_t。如果他们不同意,则没有 cookie。

    template<typename data_t>
    void bind(Wrapper<data_t>& a_data, std::type_identity_t<std::initializer_list<data_t>> a_valueList)
    

    这会阻止第二个参数中的推论。

    【讨论】:

    • 谢谢,这是一个非常有用的解决方案,我没有想过使用 type_identity_t 来区分推导的参数
    【解决方案2】:

    好的,在发布问题之前我应该​​做一些挖掘之后,我找到了这个解决方案: https://stackoverflow.com/a/34006263/17295222

    template <typename data_t>
    void Bind(Wrapper<data_t>& a_data, const std::convertible_to<data_t> auto... a_valueList) noexcept
    {
        a_data.set_data({static_cast<data_t>(a_valueList)...});
    }
    

    我要做的就是在适当的位置构造一个所需data_t类型的std::initializer_list,并在调用函数时跳过列表构造

    bind(iA,1,2,3,4,5); // works, no need for brackets
    

    【讨论】:

      猜你喜欢
      • 2021-10-09
      • 2011-03-16
      • 2018-12-12
      • 1970-01-01
      • 1970-01-01
      • 2012-01-01
      • 2016-02-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多