Preprocessor directive for a sequence that differs only in datatype
Hello Everyone, I was trying to use the boost.preprocessor to write some code which otherwise needs to be written for all the cases. Here's the code: https://github.com/BoostGSoC17/dataframe/blob/master/include/df.cpp (line no. 430 and 431). But on compilation it gives the error: error: macro "BOOST_PP_SEQ_ELEM_III" requires 2 arguments, but only 1 given print_column <BOOST_PP_SEQ_ELEM(type, INNER_TYPE) >(i); I didn't understand the reason as when I wrote: print_column <BOOST_PP_SEQ_ELEM(any_numerical_value(0, 1, ...), INNER_TYPE) >(i); it works fine. Can anyone help me understand the error or provide an alternative way to do the same thing? Thanks in advance, Best Regards, Rishabh
On 11/07/2017 19:22, Rishabh Arora wrote:
I was trying to use the boost.preprocessor to write some code which otherwise needs to be written for all the cases. Here's the code: https://github.com/BoostGSoC17/dataframe/blob/master/include/df.cpp (line no. 430 and 431). But on compilation it gives the error: error: macro "BOOST_PP_SEQ_ELEM_III" requires 2 arguments, but only 1 given print_column <BOOST_PP_SEQ_ELEM(type, INNER_TYPE) >(i);
I didn't understand the reason as when I wrote: print_column <BOOST_PP_SEQ_ELEM(any_numerical_value(0, 1, ...), INNER_TYPE) >(i); it works fine. Can anyone help me understand the error or provide an alternative way to do the same thing?
BOOST_PP_SEQ_ELEM's first parameter must be an expression resolvable at preprocessing time (usually a constant). "type" doesn't exist until runtime.
Thank you, Gavin Lambert. I don't think any of the preprocessor directives will work then? because type cannot be determined at comile time? Is there any other way to do that?
On 07/11/2017 03:09 AM, Rishabh Arora via Boost wrote:
Thank you, Gavin Lambert. I don't think any of the preprocessor directives will work then? because type cannot be determined at comile time? Is there any other way to do that?
What about replacing the switch with an index into a vector of function pointers? Something like: #include <iostream> template < class T > void print_column(std::size_t col) { T dummy; std::cout <<dummy<< std::endl; return; } using fptr=void (*)(std::size_t); fptr printers[]= { print_column<int> , print_column<float> }; int main() { unsigned ncol_=2; for(unsigned i=0; i<ncol_; ++i) { printers[i](0); } return 0; }
On 07/11/2017 06:17 AM, Larry Evans via Boost wrote:
On 07/11/2017 03:09 AM, Rishabh Arora via Boost wrote:
Thank you, Gavin Lambert. I don't think any of the preprocessor directives will work then? because type cannot be determined at comile time? Is there any other way to do that?
What about replacing the switch with an index into a vector of function pointers? Something like:
#include <iostream> template < class T > void print_column(std::size_t col) { T dummy; std::cout <<dummy<< std::endl; return; } using fptr=void (*)(std::size_t); fptr printers[]= { print_column<int> , print_column<float> }; int main() { unsigned ncol_=2; for(unsigned i=0; i<ncol_; ++i) { printers[i](0); } return 0; }
More specifically: #ifdef USE_PRINTER_TYPES template<typename... Types> struct printers { using fptr = void(data_frame::*)(size_t); static constexpr fptr _[sizeof...(Types)]= { &data_frame::print_column<Types>... }; }; using printer_types=printers<COLUMN_DATA_TYPES>; #endif//USE_PRINTER_TYPES Then, use printer_types in the data_frame::print function as: std::cout << "[" << column_headers_(i) << "]" << ": "; auto const itype=base_::operator[](column_headers_(i)).type(); #ifdef USE_PRINTER_TYPES printer_types::fptr printer=printer_types::_[itype]; (this->*printer)(i); #else switch(itype) { . . . #endif//USE_PRINTER_TYPES HTH. -regards, Larry
On 11/07/2017 20:09, Rishabh Arora wrote:
I don't think any of the preprocessor directives will work then? because type cannot be determined at comile time? Is there any other way to do that?
You might want to look at the Boost.Fusion library (http://www.boost.org/doc/libs/1_64_0/libs/fusion/doc/html/). Or if this is C++11+ code, at std::tuple and std::get. Though some of these might still require values known at compile time; depending on your usage you might be able to use constexpr methods for that, however.
On Wed, Jul 12, 2017 at 4:47 AM, Gavin Lambert via Boost < boost@lists.boost.org> wrote:
On 11/07/2017 20:09, Rishabh Arora wrote:
I don't think any of the preprocessor directives will work then? because type cannot be determined at comile time? Is there any other way to do that?
You might want to look at the Boost.Fusion library ( http://www.boost.org/doc/libs/1_64_0/libs/fusion/doc/html/).
How Can I use boost.fustion library as it requires compile time computations if I am not wrong. Please correct me if I am.
Or if this is C++11+ code, at std::tuple and std::get. Though some of these might still require values known at compile time; depending on your usage you might be able to use constexpr methods for that, however.
Can you please elaborate?
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman /listinfo.cgi/boost
participants (3)
-
Gavin Lambert
-
Larry Evans
-
Rishabh Arora