【发布时间】:2018-03-29 07:27:53
【问题描述】:
我正在尝试为back_inserter 编写一个接收器,以减少导致代码扩散的std::copy() 命令的数量。
#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>
template <typename OutputIterator>
class sink
{
public:
sink(OutputIterator out) : _out(out) { }
OutputIterator _out;
};
template <typename OI, typename C>
sink<OI>& operator<<(sink<OI>& s, const C& c)
{
std::copy(c.begin(), c.end(), s._out);
return s;
}
int main(int, const char*[])
{
std::vector<uint8_t> c;
// auto s = sink<std::back_insert_iterator<std::vector<uint8_t>>>(std::back_inserter(c));
auto s = sink(std::back_inserter(c));
s << std::vector<uint8_t>{'F','e','e','d','i','n','g',' ','f','r','o','g','g','i','e','s'};
s << std::string("Hungry hippos");
std::copy(c.begin(), c.end(), std::ostream_iterator<int>(std::cout, ":"));
}
但是这会产生错误:
main.cpp: In function 'int main(int, const char**)':
main.cpp:27:18: error: missing template arguments before '(' token
auto s = sink(std::back_inserter(c));
^
下面的代码可以工作,但不太理想,因为它看起来比到处都有大量 std::copy 函数调用更糟糕。
auto s = sink<std::back_insert_iterator<std::vector<uint8_t>>>(std::back_inserter(c));
如何提示编译器自动推断类型?
最终我想改进系统,以便我可以简单地编写
sink(out) << reply::stock_reply(reply::bad_request);
其中out 是back_insert_iterator,stock_reply 给出预设响应。
【问题讨论】:
-
尽可能使用 C++17,它已经添加了这个确切的功能:wandbox.org/permlink/RqYk2MohPJQdb72O 在此之前,C++ 只允许为函数模板扣除模板参数。
-
不行。我工作的平台仅限于 gcc4.8.4。
-
那么通常的解决方案是使用一个函数,例如
make_shared(将sink实例的构造转换为返回一些sink_class实例的函数模板的调用)。 -
"在此之前,C++ 只允许对函数模板进行模板参数的推导。"我实际上并不知道。谢谢。
标签: c++ c++11 templates type-deduction