dimanche 19 avril 2020

Why my "variadic templates function" not work in C++03

I want to implement variadic templates function in C++03.

Because I need convert my code from C++11 to C++03. I already using variadic templates function in my C++11 code.

My implement variadic template function shown as follows

#include <iostream>

#if __cplusplus >= 201103L
template <typename Type, typename... Args>
void doSomething(Args &&... args)
{
    Type data(args...);
}

#else

template <typename Type, typename Arg1>
void doSomething(const Arg1 &a1)
{
    Type data(a1);
}

template <typename Type, typename Arg1, typename Arg2>
void doSomething(const Arg1 &a1, const Arg2 &a2)
{
    Type data(a1, a2);
}
#endif
class A1
{
};

class A2
{
};

class B
{
public:
    B(A1 &a_)
        : a(a_)
    {
        std::cout << "construct B" << std::endl;
    }

private:
    A1 &a;
};

class C
{
public:
    C(A1 &a1_, A2 &a2_)
        : a1(a1_), a2(a2_)
    {
        std::cout << "construct C" << std::endl;
    }

private:
    A1 &a1;
    A2 &a2;
};

int main()
{
    A1 a1;
    A2 a2;
    doSomething<B>(a1);
    doSomething<C>(a1, a2);

    return 0;
}

It works good in C++11 g++ main.cpp -std=c++11

But It can not be compiled at C++03.g++ main.cpp -std=c++03

The compiler said that

Main.cpp: In instantiation of ‘void doSomething(const Arg1&) [with Type = B; Arg1 = A1]’:
Main.cpp:63:22:   required from here
Main.cpp:14:10: error: binding reference of type ‘A1&’ to ‘const A1’ discards qualifiers
     Type data(a1);
          ^~~~
Main.cpp:35:5: note:   initializing argument 1 of ‘B::B(A1&)’
     B(A1 &a_)
     ^
Main.cpp: In instantiation of ‘void doSomething(const Arg1&, const Arg2&) [with Type = C; Arg1 = A1; Arg2 = A2]’:
Main.cpp:64:26:   required from here
Main.cpp:20:10: error: binding reference of type ‘A1&’ to ‘const A1’ discards qualifiers
     Type data(a1, a2);
          ^~~~
Main.cpp:48:5: note:   initializing argument 1 of ‘C::C(A1&, A2&)’
     C(A1 &a1_, A2 &a2_)

Why? How can I modify my code to implement that?

Appendix

  • why I am using the const Arg1& a1 in function parameter:

I have a look at boost, it implement the variadic templates function by list the variable from 0 to N:

using boost/make_shared_object.hpp as an example

// boost/make_shared_object.hpp
template< class T, class A1 >
typename boost::detail::sp_if_not_array< T >::type make_shared( BOOST_FWD_REF(A1) a1 )

template< class T, class A1, class A2 >
typename boost::detail::sp_if_not_array< T >::type make_shared( BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2 )

template< class T, class A1, class A2, class A3 >
typename boost::detail::sp_if_not_array< T >::type make_shared( BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3 )

and I found BOOST_FWD_REF is defined as

   #define BOOST_FWD_REF(TYPE)\
      const TYPE & \
   //

Aucun commentaire:

Enregistrer un commentaire