Avoid the most annoying parsing

How do I get the compiler to create temporary partitions, use the default constructor on them without defining a function?

struct B {}; template<class T> struct C {}; template<class T,class T1> struct A { A(const T& t,const T1& t1): m_t(t),m_t1(t1) { std::cout << __PRETTY_FUNCTION__ << "\n"; } T m_t; T1 m_t1; }; int main() { A< B , C<B> > a0( B() , C<B>() ); // Function definition A< B , C<B> > a1( B b , C<B> c ); // dito, *at least A(const T& t,const T1& t1) not called } 
+4
source share
3 answers

You can transfer one of your arguments to an additional set of parentheses so that it is not parsed as a function declaration:

 A< B , C<B> > a0( (B()) , C<B>() ); 

Or even better, if you have access to the C ++ 11 compiler, use parenthesis initialization:

 A< B , C<B> > a0{ B() , C<B>() }; 
+5
source

Two ways:

  1. Initialization using assignment:

     auto a0 = A<B, C<B>>(B(), C<B>()); 

    Note that prior to C ++ 17, this changes the semantics as it requires that the copy or move constructor be available for the type (even if this is excluded, so the generated code will be the same).

  2. Use more brackets around at least one argument:

     A<B, C<B>> a0((B()), C<B>()); 

Or it works. The second method may be unreadable, and the "extra" brackets will surprise people who are not familiar with this behavior.

+5
source
 A< B , C<B> > a0((B()), (C<B>())); // ^ ^ ^ ^ 

With external parentheses, each argument can only be an expression, not a declaration.

You really need this to take place for one of the arguments, so that the entire string is not parsed as an expression. You can choose which ones or just do both.

Remember to write a comment along with code explaining that there is a good reason for the β€œextra” parentheses, otherwise God knows that someone will come and delete them once in a β€œminor” VCS commit.

+3
source

Source: https://habr.com/ru/post/1444323/


All Articles