【问题标题】:How do I pass static_cast<T> as a function?如何将 static_cast<T> 作为函数传递?
【发布时间】:2016-09-13 22:20:42
【问题描述】:

我有一个类型A,它被设计为隐式转换为类型B。这是我想在其中使用它的示例:

// Current implementation:
std::transform(vec_of_a.begin(), vec_of_a.end(), std::back_inserter(vec_of_b),
               [](const A& a) -> B { return a; });  // Thanks, Kerrek SB.

// Ideal implementation - Won't compile, expected '(' after 'static_cast'.
std::transform(vec_of_a.begin(), vec_of_a.end(), std::back_inserter(vec_of_b),
               static_cast<B>);

如何使后一个选项编译?

【问题讨论】:

  • 怎么样:std::vector&lt;B&gt; vec_of_b(vec_of_a.begin(), vec_of_a.end());?
  • @KerrekSB 这是一个很好的观点,它解决了我的特殊问题。但我仍然想知道将 static_cast 作为函数传递的最干净的方法。
  • [](const A &amp; x) -&gt; B { return x; }
  • @KerrekSB 那么,没有办法通过static_cast&lt;B&gt;?如果你把它作为答案,我会接受。
  • 无法将static_cast&lt;B&gt; 视为函数,即使它使用函数语法。

标签: c++11 functor static-cast


【解决方案1】:

static_cast&lt;B&gt;,虽然它是用函数调用语法调用的,但不能像其他可调用的东西一样传递。例如,没有办法使用&amp; 来获取指向它的函数指针。

您可以使用一个简短的小 lambda 来实现类似于将函数指针传递给 static_cast&lt;B&gt; 的功能,就像您在当前实现中所做的那样:

std::transform(vec_of_a.begin(), vec_of_a.end(), std::back_inserter(vec_of_b),
               [](const A& a) -> B { return a; });

另一种选择——在这种特殊情况下——是从vector&lt;A&gt;构造一个vector&lt;B&gt;

std::vector<B> vec_of_b(vec_of_a.begin(), vec_of_a.end());

(这个答案是对问题和bipll'sanswer的cmets的总结。)

【讨论】:

    【解决方案2】:

    构建一个包含static_cast的函子:

    template <typename T>
    struct StaticCast
    {
        template <typename U>
        T operator()(const U& rhs)
        {
            return static_cast<T>(rhs);
        }
    };
    

    有了这个,你可以拨打std::transform

    std::transform(vec_of_a.begin(), vec_of_a.end(), std::back_inserter(vec_of_b), StaticCast<b>());
    

    它可以用于已经定义输出向量来代替 cmets 中显示的 lambda 的情况。如果没有,请首选another answer**中提到的构造函数。

    如果需要,此函子版本与 C++98 兼容——即使 OP 标记为 C++11,这一点也可能值得注意。

    ** 请注意,使用此特定构造函数时,VS 编译器会引发警告 C4244(使用 VS2017 测试)。

    【讨论】:

      【解决方案3】:

      是的,这就是匿名函数在 C++ 中的工作方式,而 static_cast 不是函数,因此您不能将其地址作为映射函数传递。你必须处理它。

      你也不能使用构造函数。

      【讨论】:

      • 如果通过讨论处理方法来扩展“你必须处理它”,这个答案会更好。关于这个问题的 cmets 已经提到了许多方法。
      • @chwarr,当然,那又怎样?我是否必须在我的答案中添加“cmets 中已经提到了很多方法”?我需要复制粘贴它们吗?
      • 是的,添加实际解决方案(复制/粘贴)是可行的方法。评论不持久,以后可以删除。有了答案,至少有历史和编辑审查队列。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-02-21
      • 2014-06-29
      • 1970-01-01
      • 2016-07-23
      • 2021-10-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多