std::bind() 中 static_cast 的仿函数版本
我尝试实现 static_cast
的函子版本以在 std::bind()
中使用。
我知道 Boost ll_static_cast
(请参阅将 static_cast 与 boost::bind 结合使用) ,但我现在没有使用 Boost。
为什么几个标准运算符没有标准函子?中有一个代码示例,但它无法在 GCC 上编译4.2.1:
template <typename Target>
struct StaticCast
{
template <typename Source>
Target operator()(Source&& source) const
{
return static_cast<Target>(source);
}
}
我设法编译了一些东西,但我不确定它是否正确:
template <class Target>
struct StaticCast : public std::unary_function<void, Target> {
template <class Source>
Target operator()(Source& src) const {
return static_cast<Target>(src);
}
};
有人可以告诉我这个版本是否正确,如果是这样,为什么我需要 std::unary_function
其中前面的代码示例中没有使用到吗?
用法:
std::vector<BaseObject*> vec; // BaseObject* are known to be of type
// DerivedObject* of course, please don't ask me how or why...
std::for_each(vec.begin(), vec.end(),
std::bind(&DerivedObject::doStuff,
std::bind(StaticCast<DerivedObject*>(), std::placeholders::_1),
"with some string"));
I try to implement a functor version of static_cast
for use in std::bind()
.
I am aware of Boost ll_static_cast<K>()
(see using static_cast with boost::bind), but I am not using Boost right now.
There is a code example in Why do several of the standard operators not have standard functors? but it won't compile on GCC 4.2.1:
template <typename Target>
struct StaticCast
{
template <typename Source>
Target operator()(Source&& source) const
{
return static_cast<Target>(source);
}
}
I managed to get something to compile, but I am not sure it's correct:
template <class Target>
struct StaticCast : public std::unary_function<void, Target> {
template <class Source>
Target operator()(Source& src) const {
return static_cast<Target>(src);
}
};
Can someone tell me if this version is correct, and if this is the case, why I need std::unary_function
which is not used in the previous code example?
Usage:
std::vector<BaseObject*> vec; // BaseObject* are known to be of type
// DerivedObject* of course, please don't ask me how or why...
std::for_each(vec.begin(), vec.end(),
std::bind(&DerivedObject::doStuff,
std::bind(StaticCast<DerivedObject*>(), std::placeholders::_1),
"with some string"));
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
鉴于 C++03 中缺乏完美的转发,您必须进行重载:
请注意,我明确为
result_type
创建了typedef
,而不是继承来自std::unary_function<>
。原因是std::unary_function<>
的第一个模板参数应该是operator()
的参数类型,但是因为我们的operator( )
是一个我们无法提前知道的模板,因此一开始就提供一个模板是不诚实的(尤其是void
,这意味着operator() 为空,事实上它是一元的)。
另外,为了完整起见,以下是函子的正确 C++11 版本:
Given the lack of perfect forwarding in C++03, you'll have to make due with overloads:
Note that I'm explicitly making a
typedef
forresult_type
rather than inheriting fromstd::unary_function<>
. The reason is that the first template parameter tostd::unary_function<>
is supposed to beoperator()
's argument type, but because ouroperator()
is a template we can't know this in advance, so it's disingenuous to supply one in the first place (especiallyvoid
, which would imply thatoperator()
is nullary, when in fact it is unary).Also, for completeness' sake, here is the correct C++11 version of the functor:
第一个不起作用的一个原因可能是因为您在不支持 C++11 的编译器上使用右值引用。
您需要
std::unary_function
的原因是为您的类启用std::result_of
,std::bind
使用该类来推导结果类型,因为 C++98 中没有 decltype。如果您查看 std::unary_function ,您会发现它从您传递的模板参数中定义了类型 result_type ,该类型又由 std:: 使用直接 result_of 或
std::bind
。One reason the first one doesn't work is probably because you are using rvalue references on a compiler that doesn't support C++11.
The reason you need
std::unary_function
is to enablestd::result_of
for your class whichstd::bind
uses to deduce the result type, since there is no decltype in C++98.If you look at
std::unary_function
you will see that it defines the typeresult_type
from the template arguments you pass, which is in turned used bystd::result_of
orstd::bind
directly.好吧,通常你的代码很糟糕:
首先,你可能会遇到临时对象和右值的问题,同时请求它们的非常量引用,
例如
甚至无法编译。
然后,您在投射时制作对象的副本。这可能不是您想要的。
源示例没有由于
move
语义而产生的缺点Well, generally your code is bad:
First, you may have troubles with temporary objects and r-values while requesting non-const reference for them
for example
won't even compile.
Then, you make a copy of object while casting. It may be do not that you want.
Source example free of that disadvantages due to
move
semantics