提供按值和按引用都可用的函数版本
Providing functions versions where both by value and by reference are available
我定义了这个函数:
template <typename T>
void foo (T &result){
//some very complicate stuff
result = //something
}
现在,假设有时我想用 T=int
调用它,而在其他情况下我想用 T=std::string
调用它。因此,在第二种情况下 header 是有效的,但是 T=int
this is inefficient 是有效的。请注意,我仅使用这两种类型作为示例。
所以更好的解决方案是定义另一个函数:
template <typename T>
T foo(){
T result;
//some very complicate stuff
return result;
}
并且让用户决定调用哪个版本,但是如何避免在函数中调用整个//some very complicate stuff
的代码呢?
but with T=int
this is inefficient
启用编译器优化后,这很可能不再重要 - 重要的情况可以通过分析检测并单独处理。
but how do we avoid to call the whole code of //some very complicate stuff
in the function?
好吧,一种可能的避免方法是要求您传递一个 函数对象 作为额外参数:
template <typename T, typename F>
void foo (T &result, F&& complicated_stuff){
std::forward<F>(complicated_stuff)();
result = //something
}
template <typename T, typename F>
T foo(F&& complicated_stuff){
T result;
std::forward<F>(complicated_stuff)();
return result;
}
这是一个很好的解决方案,极有可能被编译器内联和优化...但是,如果您只想避免通过引用传递原始类型,那又有什么意义呢?我们在此处为 函数对象 添加额外的 转发引用 。
因此,我强烈建议您只拥有一个版本的foo
。按值 returns 的那个更符合 C++11 的习惯,并且不会比由于 RVO 和 移动语义 而采用引用的那个慢。
我定义了这个函数:
template <typename T>
void foo (T &result){
//some very complicate stuff
result = //something
}
现在,假设有时我想用 T=int
调用它,而在其他情况下我想用 T=std::string
调用它。因此,在第二种情况下 header 是有效的,但是 T=int
this is inefficient 是有效的。请注意,我仅使用这两种类型作为示例。
所以更好的解决方案是定义另一个函数:
template <typename T>
T foo(){
T result;
//some very complicate stuff
return result;
}
并且让用户决定调用哪个版本,但是如何避免在函数中调用整个//some very complicate stuff
的代码呢?
but with
T=int
this is inefficient
启用编译器优化后,这很可能不再重要 - 重要的情况可以通过分析检测并单独处理。
but how do we avoid to call the whole code of
//some very complicate stuff
in the function?
好吧,一种可能的避免方法是要求您传递一个 函数对象 作为额外参数:
template <typename T, typename F>
void foo (T &result, F&& complicated_stuff){
std::forward<F>(complicated_stuff)();
result = //something
}
template <typename T, typename F>
T foo(F&& complicated_stuff){
T result;
std::forward<F>(complicated_stuff)();
return result;
}
这是一个很好的解决方案,极有可能被编译器内联和优化...但是,如果您只想避免通过引用传递原始类型,那又有什么意义呢?我们在此处为 函数对象 添加额外的 转发引用 。
因此,我强烈建议您只拥有一个版本的foo
。按值 returns 的那个更符合 C++11 的习惯,并且不会比由于 RVO 和 移动语义 而采用引用的那个慢。