【发布时间】:2019-07-18 19:47:40
【问题描述】:
我开发了几个通用的读取器和写入器包装函数(主要是为了避免在读取或写入文件的代码的每个部分都必须处理异常)。我的函数有这些签名:
写作:
/** Generic writer function alias for free functions */
template<typename ... Args>
using WriterFunction = void (*)(std::ofstream &, Args const & ... args);
/**
* \brief Wrapper used to encapsulate a generic free function writing to an output stream
* \param[in] outFileName Name of the output file to be written.
* \param[in] writeFunction Function used to export the data.
* \param[in] ... Variable number of arguments to be passed to the previous function.
*/
template<typename ... Args>
void writerFunctionWrapper(
std::string const &outFileName,
WriterFunction<Args ...> writeFunction,
Args const & ... args);
阅读:
/** Generic reader function alias for free functions */
template<typename ... Args>
using ReaderFunction = void (*)(std::ifstream &, Args & ... args);
/**
* \brief Wrapper used to encapsulate a generic free function reading from an input stream
* \param[in] inFileName Name of the input file to be read.
* \param[in] readFunction Function used to import the data.
* \param[in] ... Variable number of arguments to be passed to the previous function.
*/
template<typename ... Args>
void readerFunctionWrapper(
std::string const &inFileName,
ReaderFunction<Args ...> readFunction,
Args & ... args);
因此,主要区别在于作者将输入参数视为const,因为我希望将它们读入std::ostream,反之亦然,读者将输入参数视为non-const,因为我希望通过std::istream 给他们写信。
这很好用,但我想在变量列表中包含带有 const 参数的读取器函数,或者带有 non-const 参数的写入器函数。但是,当参数列表是可变的时,我不知道该怎么做。
我尝试将我的别名和模板修改为
template<typename ... ArgsConst, typename ... ArgsNonConst>
using WriterFunction = void (*)(std::ofstream &, ArgsConst const & ... argsConst, ArgsNonConst & ... argsNonConst);
template<
typename ... ArgsConst,
typename ... ArgsNonConst>
void writerFunctionWrapper(
std::string const &outFileName,
WriterFunction<ArgsConst ..., ArgsNonConst ...> writeFunction,
ArgsConst const & ... argsConst,
ArgsNonConst & ... argsNonConst);
它的缺点是强制将参数放置在writeFunction() 中,首先是const,然后是非const,但这是一个较小的邪恶。但是,这对我不起作用:
/home/code/Utils/include/file_utils.h:42:11: error: parameter pack ‘ArgsConst’ must be at the end of the template parameter list
template<typename ... ArgsConst, typename ... ArgsNonConst>
我还尝试通过将别名和模板扩展为:
/** Generic writer function alias for free functions */
template<typename ... Args>
using WriterFunctionGeneral = void (*)(std::ofstream &, Args const & ... argsConst, Args & ... argsNonConst);
template<typename ... Args>
void writerFunctionWrapper(
std::string const &outFileName,
WriterFunctionGeneral<Args ...> writeFunctionGeneral,
Args const & ... argsConst,
Args & ... argsNonConst);
但是当我尝试在混合const 和非const 参数的函数上使用它时,这也不起作用,因为:
void writeSomeEntity(
std::ofstream &outWriter,
ConstOutVar const &constVar,
NonConstOutVar &nonConstVar);
并将其调用为:
ConstOutVar constVar;
NonConstOutVar nonConstVar;
...
Utils::writerFunctionWrapper(outFileName, &writeSomeEntity, constVar, nonConstVar);
但这也没有用:
/home/code/OutputWriter/src/entity_writer.cpp:46:122: error: no matching function for call to ‘writerFunctionWrapper(std::string&, void (*)(std::ofstream&, const ConstOutVar &, NonConstOutVar &), ConstOutVar &, NonConstOutVar &)’
Utils::writerFunctionWrapper(outFileName, writeSomeEntity, constOutVar, nonConstOutVar);
(注意错误如何显示 constOutVar & 而不是 constOutVar const &)
我注意到 [this question] (Variadic template trouble matching const and non-const std::string),但这并不是我在这里描述的情况。
有什么建议吗?
非常感谢。
【问题讨论】:
-
这很好用,但我已经到了一个地步,我希望在其变量列表中拥有带有 const 参数的读取器函数,或者带有非 const 参数的写入器函数. 为什么?您不能在阅读器中修改 const 对象,也不应该修改正在编写的对象。
-
@NathanOliver,为什么不呢?例如,我可以使用一些参数来返回我写入的字节数。甚至可以将此示例视为更通用的示例,而不仅仅是与读者或作者相关联,假设您要传递一组可变变量,一些是 const,一些是非 const。
-
@A.Palma 首先,您应该避免使用 out 参数。如果您需要从函数返回数据,这就是返回类型的用途。其次,您可以将非常量对象传递给采用
const&的函数。在 write 函数中将参数设置为const可以防止您犯意外错误。
标签: c++ variadic-templates template-argument-deduction