English 中文(简体)
c++ 模板功能,有不同的论据
原标题:c++ template functions with variable arguments

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

现在,我的冷静做法本来会(限于最多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) {
    ...
}

当然,正如我说的那样,这 st了有关违约论点的职能,而且我们已经获得。

error: default template arguments may not be used in function templates

但实际上,它用gcc和-std=c++0x汇编。 然而,显然,<代码>sql_query(>>> 仍没有多少长度投入,需要用2个矢量来打上。 此外,我还想就目前大多数汇编者开展一些有益的工作。 任何一个显而易见的我都被忽视了吗? 我知道,我可以改变设计和可能使用<代码>boost:tuple。 否则,我就喜欢这样简单的接口。

最佳回答

如上所述,Boost。 如果不提供C++0x,则加工商是行走的路,尽管它需要一个时间才能被用到yn子上。 下面的例子说明了诱杀的方式。 预审程序者可以用来界定各种(但有限的)理由。

#include <boost/preprocessor/repetition.hpp>
#include <boost/preprocessor/iteration/local.hpp>
#include <boost/preprocessor/iteration/iterate.hpp>

#define MAX_PARAMS  2

class sql {
public:
   // definition of the function in macro form
   #define SQL_QUERY_DEF(z, n, unused)                                     
   template <BOOST_PP_ENUM_PARAMS(n, class T)>                             
   void query(const std::string& query,                                    
            BOOST_PP_ENUM_BINARY_PARAMS(n, const T, & x) );

   // does the actual code replication of SQL_QUERY_DEF
   #define BOOST_PP_LOCAL_MACRO(n)  SQL_QUERY_DEF(~, n, ~)
   #define BOOST_PP_LOCAL_LIMITS    (1, MAX_PARAMS)
   #include BOOST_PP_LOCAL_ITERATE()

   ...
};


// two helper functions:
// expands to var0.clear(); var1.clear(); ...
#define SQL_VECTOR_CLEAR(z,i,var) var##i.clear();
// expands to var0.push_back(this->get_col<T0>(0); ...
#define SQL_VECTOR_PUSH_BACK(z,i,var) var##i.push_back(this->get_col<T##i>(i));

// definition of the function in macro form
#define SQL_QUERY(z, n, unused)                                               
template <BOOST_PP_ENUM_PARAMS(n, class T)>                                   
void sql::query(const std::string& query,                                     
                  BOOST_PP_ENUM_BINARY_PARAMS(n, std::vector< T,>& x) ){      
   this->do_query(query);                                                     
   if(this->num_cols()<n){                                                    
      throw std::runtime_error();                                             
   }                                                                          
   BOOST_PP_REPEAT(n, SQL_VECTOR_CLEAR, x)                                    
   while(this->is_open()) {                                                   
      BOOST_PP_REPEAT(n, SQL_VECTOR_PUSH_BACK, x)                             
      this->step();                                                           
   }                                                                          
}

// does the actual code replication of SQL_QUERY
#define BOOST_PP_LOCAL_MACRO(n)  SQL_QUERY(~, n, ~)
#define BOOST_PP_LOCAL_LIMITS    (1,  MAX_PARAMS)
#include BOOST_PP_LOCAL_ITERATE()

加工前者将这一点扩大到:

$ g++ -P -E sql.cpp | astyle

class sql {
public:
   template < class T0> void query(const std::string& query, const T0 & x0 );
   template < class T0 , class T1> void query(const std::string& query, const T0 & x0 , const T1 & x1 );
   ...
};
template < class T0> void sql::query(const std::string& query, std::vector< T0 >& x0 ) {
   this->do_query(query);
   if(this->num_cols()<1) {
      throw std::runtime_error();
   }
   x0.clear();
   while(this->is_open()) {
      x0.push_back(this->get_col<T0>(0));
      this->step();
   }
}
template < class T0 , class T1> void sql::query(const std::string& query, std::vector< T0 >& x0 , std::vector< T1 >& x1 ) {
   this->do_query(query);
   if(this->num_cols()<2) {
      throw std::runtime_error();
   }
   x0.clear();
   x1.clear();
   while(this->is_open()) {
      x0.push_back(this->get_col<T0>(0));
      x1.push_back(this->get_col<T1>(1));
      this->step();
   }
}

注 BOOST_PP_REPEAT(import_PARAMS,_questRY, ~),因为它以0参数开始推广,但我们必须从1开始,这说明为什么。 BOOST_PP_LOCAL_ITERATE () is need that is more Flex.

问题回答

在C++0x中,通过弹道模板实现了这一点(论点数目可能很大,但仅限于具体实施)。

在C++03中,通过采用加工前宏观方法,产生多种精度的模范功能(见Boost.Preprocessor)。

I ve used the C++03 technic to generate the "bind" from 1 to 10 arguments and it works pretty well.





相关问题
Undefined reference

I m getting this linker error. I know a way around it, but it s bugging me because another part of the project s linking fine and it s designed almost identically. First, I have namespace LCD. Then I ...

C++ Equivalent of Tidy

Is there an equivalent to tidy for HTML code for C++? I have searched on the internet, but I find nothing but C++ wrappers for tidy, etc... I think the keyword tidy is what has me hung up. I am ...

Template Classes in C++ ... a required skill set?

I m new to C++ and am wondering how much time I should invest in learning how to implement template classes. Are they widely used in industry, or is this something I should move through quickly?

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

typedef ing STL wstring

Why is it when i do the following i get errors when relating to with wchar_t? namespace Foo { typedef std::wstring String; } Now i declare all my strings as Foo::String through out the program, ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

Window iconification status via Xlib

Is it possible to check with the means of pure X11/Xlib only whether the given window is iconified/minimized, and, if it is, how?

热门标签