我有一个可变参数模板函数,它将文件名、分隔符和非指定数量的容器作为参数作为列。然后,此函数解析以将所有值归档到表示列的容器中,并在所有值之间放置分隔符。
bool parseToFile (const std::string& file, const char delimiter, auto&... columns)
{
bool done {false};
std::ofstream out;
out.open (file, std::ios::out | std::ios::trunc);
if (!out)
{
done = false;
std::cout << "SaveFile: Cannot open file: " << file << "!" ;
std::cout << std::strerror (errno) << std::endl;
}
else
{
std::size_t maxContainerSize {0};
auto maxSize = [&maxContainerSize] (std::size_t containerSize)
{
maxContainerSize = std::max (maxContainerSize, containerSize);
};
(maxSize (columns.size()), ...);
std::size_t i {0};
auto implementation = [&i, delimiter, &out] (auto & cont, std::size_t s)
{
if (i < cont.size())
out << cont[i];
out << delimiter;
};
for (; i < maxContainerSize; ++i)
{
(implementation (columns, columns.size()), ...);
out << "\n";
}
out << std::flush;
done = true;
return done;
}
这可以正确地按预期工作。
但是这个模板有几个与参数包“列”相关的限制
我应该如何更改代码来实现此约束?
我试过这个:
template <template <typename, typename> class Container,
typename Value,
typename Allocator = std::allocator<Value>>
concept containerHasPrintable = requires (std::ostream& out, Container<Value,Allocator>& data)
{
out << data[0];
};
// and definition:
bool parseToFile (const std::string& file, const char delimiter, containerHasPrintable&... columns);
但这不起作用。海湾合作委员会 13.1
main.cpp|80|错误:模板参数数量错误(1,应该至少为 2)| 《80-功能》 main.cpp|40|注意:为“template类Container、类Value、类Allocator>概念containerHasPrintable”|提供《40-概念》 main.cpp|80|错误:扩展模式“int&”不包含参数包|
如何约束模板?
这个:
template <template <typename, typename> class Container,
typename Value,
typename Allocator = std::allocator<Value>>
concept containerHasPrintable = /* ... */;
是一个限制三个事物的概念:一个模板和两种类型。但这实际上并不是您想要的 - 您想要一个限制一个事物的概念:类型。
所以你想写的就是:
template <typename Container>
concept PrintableContainer = requires (std::ostream& out, Container& data)
{
out << data[0];
};
请注意,您的概念中的其他内容实际上都不相关 - 无论如何,您不需要容器特别看起来像
C<V, A>
- 这只是武断地拒绝了一些其他可以工作的类型(例如,std::string
)。