c++具有可变参数的模板函数
是否可以编写一个 C++ 模板函数,它接受不同数量的不同类型的输入变量(输入数量可以限制为 10 个)? 例如,采用一个函数sql_exec()
,它执行一个sql查询字符串并将结果行保存在所提供类型的std向量中,即
std::vector<double> x,y;
std::vector<std::string> s;
std::string query="select * from ...";
sql_exec(query, s,x,y); // error if less than 3 rows or conversion not possible
现在我天真的方法是(限制为最多2个向量)
struct null_type {};
template <typename T1=null_type, typename T2=null_type>
void sql_query(const std::string& query_str, std::vector<T1>& col1,
std::vector<T2>& col2) {
...
}
的当然这很愚蠢,因为我没有告诉函数有关默认参数的信息,
error: default template arguments may not be used in function templates
但实际上它是使用 gcc 和 -std=c++0x 进行编译的。然而,显然sql_query()
仍然不接受可变长度输入,需要用2个向量来调用。另外,我希望有一些可移植的东西可以在大多数当前的编译器上工作。有什么明显的我忽略的事情吗?我知道我可以改变设计,也许可以使用 boost::tuple 或其他东西,但我喜欢这样一个简单的界面。
Is it possible to write a c++ template function which takes a variable number of input variables of different types (number of input can be limited to say 10)?
For example take a function sql_exec()
which executes an sql query string and saves the resulting rows in std vectors of the type supplied, i.e.
std::vector<double> x,y;
std::vector<std::string> s;
std::string query="select * from ...";
sql_exec(query, s,x,y); // error if less than 3 rows or conversion not possible
Now my naive approach would have been (limited to max 2 vectors)
struct null_type {};
template <typename T1=null_type, typename T2=null_type>
void sql_query(const std::string& query_str, std::vector<T1>& col1,
std::vector<T2>& col2) {
...
}
Of course that's stupid as I didn't tell the function about default arguments and we get
error: default template arguments may not be used in function templates
but actually it compiles with gcc and -std=c++0x
. However, obviously sql_query()
still doesn't take variable length input and needs to be called with 2 vectors. Also, I'd like to have something portable working on most of the current compilers. Anything obvious I've overlooked? I know I can change the design and maybe use boost::tuple
or something else but I'd have liked such a simple interface.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在 C++0x 中,这是通过可变参数模板实现的(参数的数量可能会很大,限制是特定于实现的)。
在 C++03 中,这是通过让预处理器宏生成大量不同数量的模板函数来模拟的(请参阅 Boost.Preprocessor)。
我使用 C++03 技术生成 1 到 10 个参数的“绑定”,并且效果很好。
In C++0x this achieved through variadic templates (and the number of arguments can get huge, limit being implementation specific).
In C++03, this is emulated by having preprocessor macros generating lots of template functions of various arity (see Boost.Preprocessor).
I've used the C++03 technic to generate the "bind" from 1 to 10 arguments and it works pretty well.
如上所述,如果 C++0x 不可用,Boost.Preprocessor 是可行的方法,尽管需要一段时间来习惯语法。下面的示例演示了如何使用 Boost.Preprocessor 来定义具有可变(但有限)数量的参数的函数。
预处理器将其扩展为:
注意,这里我们不能使用 BOOST_PP_REPEAT(MAX_PARAMS, SQL_QUERY, ~),因为它以 0 个参数开始复制,但我们需要从 1 个参数开始,这就是为什么
BOOST_PP_LOCAL_ITERATE需要使用()
,这样比较灵活。As said above, Boost.Preprocessor is the way to go if C++0x is not available, although it takes a while to get used to the syntax. The example below demonstrate the way Boost.Preprocessor can be used to define functions with variable (but limited) number of arguments.
The preprocessor expands this to:
Note, here we can't use
BOOST_PP_REPEAT(MAX_PARAMS, SQL_QUERY, ~)
as it starts replication with 0 parameters but we need to start with 1, that's whyBOOST_PP_LOCAL_ITERATE()
is needed which is more flexible.