有没有办法放置返回值
Is there a way to emplace return value?
// VERSION 1
struct Range { int begin, end; };
inline Range getRange()
{
int newBegin, newEnd;
// do calculations
return {newBegin, newEnd};
}
struct Test
{
std::vector<Range> ranges;
inline void intensive()
{
ranges.push_back(getRange());
// or ranges.emplace_back(getRange());
// (gives same performance results)
}
};
// VERSION 2
struct Range { int begin, end; };
struct Test
{
std::vector<Range> ranges;
inline void intensive()
{
int newBegin, newEnd;
// do calculations
ranges.emplace_back(newBegin, newEnd);
}
};
版本 2 始终比版本 1 快。
事实上,getRange()
被多个类使用。如果我应用版本 2,会有很多代码重复。
另外,我不能将ranges
作为对getRange()
的非常量引用传递,因为其他一些类使用std::stack
而不是std::vector
。我将不得不创建多个重载并有更多的代码重复。
是否有常用方法/习惯用语来放置返回值?
在评论中讨论使用 SFINAE 允许放置在任何类型的容器上(无论它支持 emplace
还是 emplace_back
(,这里有一个示例实现。
您只需要一种方法来检测emplace
或emplace_back
是否可用,并相应地调度呼叫。为此,我们将使用 SFINAE:
namespace detail
{
template<typename T, typename... Args>
auto emplace_impl(int, T& c, Args&&... pp)
-> decltype(c.emplace_back(std::forward<Args>(pp)...))
{
return c.emplace_back(std::forward<Args>(pp)...);
}
template<typename T, typename... Args>
auto emplace_impl(long, T& c, Args&&... pp)
-> decltype(c.emplace(std::forward<Args>(pp)...))
{
return c.emplace(std::forward<Args>(pp)...);
}
} // namespace detail
template<typename T, typename... Args>
auto emplace(T& c, Args&&... pp)
-> decltype(detail::emplace_impl(0, c, std::forward<Args>(pp)...))
{
return detail::emplace_impl(0, c, std::forward<Args>(pp)...);
}
向@DyP致敬,他们提供了这个更好,更短的C++11解决方案(见评论(。以前基于特征的解决方案(修订版3和4(要冗长得多。
使用它非常简单:
template<typename Container>
void test_emplace()
{
Container c;
emplace(c, 3);
}
int main()
{
test_emplace<std::queue<int>>();
test_emplace<std::stack<int>>();
test_emplace<std::deque<int>>();
test_emplace<std::list<int>>();
test_emplace<std::vector<int>>();
}
我会让你弥合我的test_emplace()
使用示例和你的实际代码之间的差距,但现在应该不会太难。 ;)
这里有一种方法可以将代码传递到GetRange
中,而不知道您要放入什么:
template<typename Emplacer>
void GetRange( Emplacer emplace ) {
int beg, end;
// ...
emplace( beg, end );
}
std::vector<Range> ranges;
inline void intensive()
{
GetRange( [&]( int b, int e ) {
ranges.emplace_back( b, e );
} );
}
不,您正在用getRange()
进行构造,emplace_back
在vector
中完成了构造。
相关文章:
- 有没有办法使用递归函数找到数组中最小值的 INDEX?C++
- 有没有办法按值将纯抽象类的所有子类传递给 C++ 中的函数?
- 有没有办法找到特征矩阵系数的中值?
- 有没有办法一次声明相同类型的多个对象,并通过一个表达式立即使用相同的右值初始化它们?
- 有没有办法在从临时返回按值string_view时获得编译器警告?
- 如果函数的返回值将用作右值引用而不是左值,有没有办法使函数具有不同的行为?
- 为什么 GCC 无法优化,除非返回值有名称?
- 有没有办法为任何函数编写通用代码,以便它可以(异步)执行并从线程池中获得返回值?
- 程序未完成返回值3221225477没有编译器错误
- memset() 返回值有什么用?
- 有没有办法在C++11中匹配返回值
- 在JNA中,GlobalAlloc和GlobalLock的返回值有什么不同
- 有没有办法使用 move 而不是复制语义将函数返回值(对象)包装在 Python 中
- 有没有办法放置返回值
- 为什么没有捕获返回值时没有错误
- 用户定义函数的返回值有问题
- 如何判断有返回值的函数没有结果
- try-catch对char**返回值有影响
- 有没有一种惯用的方法可以返回一个指针,该指针可以选择拥有其值
- 有没有办法区分new和new[]的返回值?