【问题标题】:Cast specific types in variadic argument在可变参数中强制转换特定类型
【发布时间】:2019-03-08 09:07:19
【问题描述】:

我有一个接受可变参数的模板函数。

template<typename... Params>
void foo(Params... p);

我想在Params 中找到给定类型(const char*)的所有出现,以将它们替换为另一种类型,这些值可以转换为(我自己的Path 类和构造函数Path(const char*))。这个想法是有类似的东西

template<typename... Params>
void foo(Params... p) {
    bar<convertCharPointerToPath<Params>...>(p...);
}

如何进行这种转换?

【问题讨论】:

  • 你的问题是什么?

标签: c++ casting variadic-templates variadic-functions


【解决方案1】:

如果你只想转换类型,它只是一个元函数:

template<typename T> struct convert {
  using type = T;
};

template<> struct convert<char const*> {
  using type = Path;
};

template<typename T>
using convertCharPointerToPath = typename convert<T>::type;

现在在您的参数包扩展中使用它,就像您在原始帖子中所做的那样。

【讨论】:

  • 您也可以使用std::conditional_t,但不确定这是否比您所拥有的更具可读性。
  • @Rakete1111 - 我发现拼写某些元功能更容易理解,我自己。当然,条件会产生相同的效果。但我认为这更容易扩展到其他类型。
  • 在我的情况下扩展到std::string ;)
【解决方案2】:

没有特征助手:

template<typename... Params>
void foo(Params... p) {
  bar<std::conditional_t<std::is_same<char const*,Params>{},Path,Params>...>(p...);
}

或者,overload&lt;Fs...&gt;:

auto identity=[](auto&&x)->decltype(x){return decltype(x)(x);};

template<typename... Params>
void foo(Params... p) {
  auto convert = overload([](const char* p){return Path(p);},identity);
  bar(convert(p)...);
}

overload 随处可见;它需要一组 lambda 表达式并返回它们的重载集。

Live example.

【讨论】:

  • 我正在尝试使用overload 版本来解决类似的问题,但我无法让它工作。编译器抱怨它找不到overload 对象的可行构造函数。问题可能是不同的重载有不同的返回类型?
  • @NikolausDemmel 或者你想要的overload 的版本需要{}?还是扣分指南?或者您的编译器不支持演绎指南?很多东西都可能出错。
  • @NikolausDemmel 添加了编译实时示例链接。
  • 感谢现场示例。事实证明,我的 bar 有问题。它现在对我有用。对于超载,您有overload(Fs&amp;&amp;...)-&gt;overload&lt;std::decay_t&lt;Fs&gt;...&gt;;,而我有overload(Fs...)-&gt;overload&lt;Fs...&gt;;(来自其他地方)。就我而言,两者都有效。我真的不明白什么时候会有所作为。
  • @NikolausDemmel 使用“提问”按钮提问是件好事。 :)
猜你喜欢
  • 2012-06-20
  • 2014-02-16
  • 1970-01-01
  • 2021-01-24
  • 1970-01-01
  • 1970-01-01
  • 2012-11-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多