// 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
作为非const引用传递给getRange()
,因为其他一些类使用的是std::stack
而不是std::vector
。我将不得不创建多个重载并有更多的代码重复。
是否有一个共同的方式/习惯用法来表示返回值?
答案 0 :(得分:4)
在关于使用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()
使用示例与实际代码之间的差距,但现在不应该太难。 ;)
答案 1 :(得分:3)
以下是一种方法,您可以将代码传递给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 );
} );
}
答案 2 :(得分:1)
不,您正在使用getRange()
进行构建,其中emplace_back
已在vector
中完成构建。