【问题标题】:Cast from type parametrized by const template argument to non-const template argument从由 const 模板参数参数化的类型转换为非 const 模板参数
【发布时间】:2021-09-02 03:41:26
【问题描述】:

我有一个带有可变模板参数的类:

template<typename... Args>
class something {
public:
  something(Args&&... args); // omitted for brevity
}

我有一个接受参数列表并返回此类对象的函数:

template<typename... Args>
auto make_something(Args&&... args) {
    return something<Args...>(std::forward<Args>(args)...);
}

如果我这样称呼它:

something<int, std::string> s = make_something<int, std::string>(1, "");

它可以编译并且工作正常。

但是如果我尝试传递一个 const 参数,我会得到编译错误:

const std::string t = "";
something<int, std::string> s1 = make_something(1, t); // no viable conversion from something<... const basic_string<char>> to something<... std::string>

如何成功传递 const,然后 idk 将结果转换为请求的类型,由非 const 类型参数化?

我怀疑这与我返回的对象的类型有关,但我实际上不知道在这种情况下用什么替换 auto

【问题讨论】:

  • 请注意,您的构造函数 something(Args&amp;&amp;...); 不使用转发引用,因为类型是由类固定的。
  • @Jarod42 我不确定我是否完全理解你的意思。您是否建议我从带有模板参数 A1 和 Args1 的参数中对构造函数进行参数化...?或者你的意思是我没有调用std::forward 来传递参数——因为我是,只是我省略了成员初始化列表。

标签: c++ templates variadic-templates


【解决方案1】:

有两种选择,具体取决于您是否真的想让something&lt;int, const std::string &amp;&gt; 成为make_something(1, t) 返回的类型。

如果是这样,你可以有一个转换构造函数

template<typename... Args>
class something {
public:
  something(Args&&... args); // omitted for brevity
  template<typename... OtherArgs> 
  something(something<OtherArgs...>); // convert each OtherArgs into Args
}

或者,您希望make_something(1, t) 产生something&lt;int, std::string&gt;

template<typename... Args>
class something {
public:
  template<typename... OtherArgs> 
  something(OtherArgs&&...); // use each OtherArgs for Args
}

template <typename... Args>
auto make_something(Args&&... args)
{
    return something<std::decay_t<Args>...>(std::forward<Args>(args)...);
}

【讨论】:

  • 谢谢!第二个选项是我需要的。但是,我仍然无法让它工作,我怀疑构造函数有问题(正如我猜想,在原始问题的 cmets 中指出的那样)。您能在这里展示一下 args 的构造函数应该是什么样子吗?因为我一直只是转发它们,但我想这……还不够吗?构造函数是否也应该有自己的模板参数?
  • @wouldnotliketo 这是因为你的构造函数是为那些确切的类型定义的,而不是接受任何衰减成这些类型的东西
【解决方案2】:

您可能会这样做(如果相关):

template <typename... Args>
auto make_something(Args&&... args)
{
    return something<std::decay_t<Args>...>(std::forward<Args>(args)...);
}

所以你得到了something&lt;int, std::string&gt; 而不是something&lt;int, const std::string&amp;&gt;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-25
    • 1970-01-01
    相关资源
    最近更新 更多