1

In my program I want to define a new data-type for IPAddressV4 for this purpose I defined the following class:

#include <boost/array.hpp>
#include <boost/asio.hpp>

#include "archive.hpp"

using boost::asio::ip::address_v4;
typedef boost::uint8_t     uint8;   /**< 8-bit unsigned interger.   */

class IPAddrV4
{
public:
/**
 * Construct a IPAddrV4 data type.
 */
IPAddrV4() : _ip_address(0)
{}


/**
 * Construct a IPAddrV4 data type.
 *
 * @param ip_address The value of the IPv4 Address in text format.
 */
IPAddrV4(std::string ip_address) : _ip_address(0)
{
    *this = ip_address;
}

/**
 * Set the IPv4 Address value.
 *
 * @param val The value of the IPv4 Address in text format.
 * @return The reference to the IPAddrV4 data type.
 */
IPAddrV4& operator=(std::string ip_address)
{
    boost::asio::ip::address_v4::bytes_type bytes
            = boost::asio::ip::address_v4::from_string(ip_address).to_bytes();

    _ip_address = ((uint32(bytes.at(0)) << 24) |
                   (uint32(bytes.at(1)) << 16) |
                   (uint32(bytes.at(2)) <<  8) |
                    uint32(bytes.at(3)));

    return *this;
}

IPAddrV4& operator=(uint32 ip_address)
{
    _ip_address = ip_address;
    return *this;
}

/**
 * Get the IPv4 Address data type value.
 *
 * @return The IPv4 Address data type value in binary form.
 */
operator uint32()
{
    return _ip_address;
}

private:
    uint32 _ip_address;

};

Later I am using this class to do some serialization and deserialization to send data over a TCP connection. When I am doing serialization with an output archive, I don't have any problem.

IPAddrV4 ip("127.0.0.1");
oarchive & ip;

In the above example, the value of the IP is converted into binary form and then copied to the output archive. And the oarchive will increase its size by 4 Bytes.

But when I try to use this data-type with the input archive for serialization I get problem:

IPAddrV4 ip;
iarchive & ip;

This is the error which I get while compiling:

No match for 'operator&' in 'input_Archive & IPAddrV4::operator uint32()'

So what am I missing in the IPAddrV4?

Note: The input archive works perfectly with the standard c++ data-types like uint,string..etc.

IoT
  • 607
  • 1
  • 11
  • 23
  • One observation: you're writing a constructor in terms of an assignment. Don't do that, it's horribly inefficient. Write your assignment in terms of a constructor followed by swap. – Richard Hodges May 04 '14 at 22:51
  • I am not sure I got you correctly, can you explain more amd say why it's inefficient? – IoT May 04 '14 at 22:55
  • 1
    A constructor will fully initialise all members prior to the first "{". Your constructor does that and then calls *this = ip_address, which invokes a call to the assignment operator. In effect, it assigns values to the member variables twice. – Richard Hodges May 04 '14 at 22:59

2 Answers2

1

Boost Serialization has the BOOST_STRONG_TYPEDEF for this purpose.

See also

Community
  • 1
  • 1
sehe
  • 374,641
  • 47
  • 450
  • 633
  • So @sehe, my problem is because I didn't overload an operator? I should use BOOST_STRONG_TYPEDEF which makes the job for me, correct? – IoT May 04 '14 at 22:40
  • I am not using the archive of Boost, sorry I should have mentioned that. I have my own classes for input and output archive. So does BOOST_STRONG_TYPEDEF still work for me? – IoT May 04 '14 at 22:58
  • 1
    Strong typedefs work at the front end (selecting the serialization implementations for your class), not the back end, so you're good. – sehe May 04 '14 at 23:00
  • I tried now to do for my data-type `BOOST_STRONG_TYPEDEF (IPAddrV4, IPADDRESS)`, but I got the same error. Maybe I got it wrong – IoT May 04 '14 at 23:06
  • Erm. If you wanted to _"define a new data-type that behaves like a standard c++ data-type"_ (see your question title), that should have bee just `BOOST_STRONG_TYPEDEF(uint32_t, IPADDRESS)`. Of course, when you just typedef the already not-working type, then it will /still/ not-work :) – sehe May 05 '14 at 00:08
1

I found the error, I have to change the overloading of the operator uint32() to be uint32&() as following:

operator uint32 &()
{
    return _ip_address;
}

In this way I return value by reference not by value for the input archive.

sehe
  • 374,641
  • 47
  • 450
  • 633
IoT
  • 607
  • 1
  • 11
  • 23