Click here to Skip to main content
15,883,883 members

Comments by Lukasz Gwizdz (Member 2097797) (Top 5 by date)

Lukasz Gwizdz (Member 2097797) 4-Apr-13 6:55am View    
Initially, I also mistook multiple flies for multiple files ;D
Regards.
Lukasz Gwizdz (Member 2097797) 11-Mar-13 18:12pm View    
Yes, indeed. I also realized it later. Perfect forwarding does the job here. Because of std::forward, the entire tag dispatching with store() layer is useless. It does redundant job. I cannot comprehend now why I did it. Anyway, C++ rocks! ;)

Thanks for info. Should I update the answer?
Lukasz Gwizdz (Member 2097797) 11-Mar-13 9:58am View    
I'm not sure what are you trying to accomplish.
I think that phrase "from client" in this context is misleading.
Change the wording. Eg. something like this:

// print info about server, it is sufficient to print it once
printf("Server: Server is listening on: %s:%d\n", inet_ntoa(ServerAddr.sin_addr), htons(ServerAddr.sin_port));

// print info about client
printf("Server: Connected peer: %s:%d\n", inet_ntoa(SenderInfo.sin_addr), htons(SenderInfo.sin_port)); // or "Received connection from: %s:%d\n"
Lukasz Gwizdz (Member 2097797) 11-Mar-13 9:44am View    
Richard is right. Moreover, keep in mind that getsockname() is for local socket, and getpeername() is for remote. And one more thing, 0.0.0.0 is ANY (INADDR_ANY) address, the address which server is bound to (this info is sufficient to figure out what's wrong). For the first look, you are doing everything fine (getsockname for server's ListeningSocket, and getpeername for remote's NewConnection).
You printing info about server listening socket as it would be remote connected socket.
Eg.:
printf("Server: Receiving port from client: %d\n", htons(ServerAddr.sin_port));
ServerAddr.sin_port is not client port, this is port of server's listening socket.
This is remote port:
printf("Server: Sending port used: %d\n", htons(SenderInfo.sin_port));
ServerAddr stores data about server, and SenderInfo about connected remote peer (client). So, I think that your expectations about output log are wrong.
You just need to change your log output. "Sending IP..." should become "Receiving IP..."
Lukasz Gwizdz (Member 2097797) 3-Mar-13 16:59pm View    
Hello again!

Yeah, You have right. I forgot about removing topomost cv-qualifiers. But, as I see, you managed to fix it easily. And you have right too. There is no std::remove_const_reference. You need to compose type traits in order to accomplish such effect. In my opinion, it is correct that there isn't remove_const_reference. Such trait would be serving two purposes. The fine grain of highly related type traits supports high cohesion. The only type trait class I can think about which in fact is composed of two operations is std::remove_cv (and std::add_cv) - which, in general, removes cv-qulifiers (const or volatile). For your purposes you can compose such classes on your own eg.:
template< class T >
struct remove_const_reference {
typedef typename std::remove_const<typename std::remove_reference<t="">::type>::type type;
};

In this case you can also use template alias. So revised version could look like this:
class my_class
{
// A, B and C types defined elsewhere...

typedef std::shared_ptr a_ptr_type;
typedef std::shared_ptr< B> b_ptr_type;
typedef std::shared_ptr<c> c_ptr_type;

a_ptr_type a_ptr_;
b_ptr_type b_ptr_;
c_ptr_type c_ptr_;

template<class t=""> T&& store_impl(T&& v, std::false_type const& )
{
return std::forward<t>( v );
}
template<class t=""> T&& store_impl(T&& v, std::true_type const& )
{
return std::move( v );
}
template<class type="">
Type&& store(Type&& v)
{
return store_impl(std::forward<type>(v),
typename std::is_rvalue_reference<type>::type());
}

template<class t="">
using remove_const_reference = typename std::remove_const<typename std::remove_reference<="" t="">::type>;

// if your compiler has a problem with template aliases use classical approach:
// template< class T >
// struct remove_const_reference {
// typedef typename std::remove_const<typename std::remove_reference<t="">::type>::type type;
// };

public:

template < class Type, class U, typename std::enable_if< std::is_same< B,
typename remove_const_reference< U >::type >::value, int >::type = 0 >
my_class(Type&& a, U&& b) :
a_ptr_(std::make_shared< A >(std::forward< Type >(a))),
b_ptr_(std::make_shared< B >(store(std::forward< U >(b)))),
c_ptr_(nullptr)
{
}

template < class Type, class U, typename std::enable_if< std::is_same< C,
typename remove_const_reference< U >::type >::value, int >::type = 0 >
my_class(Type&& a, U&& c) :
a_ptr_(std::make_shared< A >(std::forward< Type >(a))),
b_ptr_(nullptr),
c_ptr_(std::make_shared< C >(store(std::forward< U >(c))))
{
}

// ...
};

Depending on your needs you can even create your own traits using partial template specialization (see implementation of type_traits or boost::type_traits library as well). Remember that you can always use std::true_type or std::false_type to conform standard behaviour/interface eg.:
// similar to std::is_same
template<class t,="" class="" u="">
struct is_same_type : std::false_type
{};
template<class t="">
struct is_same_type<t,t> : std::true_type { };

// another example, notice usage using declaration instead of typedef declaration
using False = std::false_type;
template<class t="">
struct is_pointer : False
{};

typedef std::true_type True;
template<class t="">
struct is_pointer<t*> : True
{};

Of course, if you don't want use std::integral_constant (std::true_type, std::false_type) you may always define your classes eg.:
struct True
{
static constexpr bool value = true;
};
struct False
{
static constexpr bool value = false;
};

Anyway, thank you for accepting my solution.
It was very kind and definitely made my day ;)

Regards!
Lukasz Gwizdz