Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Packets and vector?  (Read 5410 times)

0 Members and 1 Guest are viewing this topic.

ritave

  • Newbie
  • *
  • Posts: 26
    • View Profile
Packets and vector?
« on: December 30, 2009, 02:10:09 pm »
So I wanted to make packets able to receive and send vectors, but I've encountered some problems with templates.
The problem is, how to make overloading vectors without knowing vectors template, I'm using something like this
Code: [Select]

template<class T>
sf::Packet& operator <<(sf::Packet& Packet, const std::vector<T>& A)
{
Packet << A.size();
for (int i=0;i<A.size();i++)
{
Packet << A[i];
}
return Packet;
}

template<class T>
sf::Packet& operator >>(sf::Packet& Packet, std::vector<T>& A)
{
unsigned int size;
Packet >> size;
A.reserve(size);
for (int i=0;i<size;i++)
{
T temp;
Packet >> temp;
A.push_back(temp);
}
return Packet;
}


and calling it

Code: [Select]

sf::Packet& operator <<(sf::Packet& Packet, const Welcome_Accept& A)
{
return Packet << A.UserId << A.UserList;
}
sf::Packet& operator >>(sf::Packet& Packet, Welcome_Accept& A)
{
return Packet >> A.UserId >> A.UserList;
}


But that doesn't quite work, the error says that no such overloaded operator found

Ps. Forgot, UserList is std::vector<New_User>
and yes, New_User has overloaded operators

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Packets and vector?
« Reply #1 on: December 30, 2009, 02:57:15 pm »
Works for me.

Can you post a complete and minimal piece of code that reproduces the problem? Can you give the exact error message?
Laurent Gomila - SFML developer

ritave

  • Newbie
  • *
  • Posts: 26
    • View Profile
Packets and vector?
« Reply #2 on: December 30, 2009, 03:26:55 pm »
There we go, I'm including whole file, well... Since I don't really know why the problem appears.

Code: [Select]

//PacketTypes.h
#pragma once

#include <SFML/System.hpp>
#include <SFML/Network.hpp>
#include <string>
#include <vector>

template<class T>
sf::Packet& operator <<(sf::Packet& Packet, const std::vector<T>& A)
{
Packet << A.size();
for (int i=0;i<A.size();i++)
{
Packet << A[i];
}
return Packet;
}

template<class T>
sf::Packet& operator >>(sf::Packet& Packet, std::vector<T>& A)
{
unsigned int size;
Packet >> size;
A.reserve(size);
for (int i=0;i<size;i++)
{
T temp;
Packet >> temp;
A.push_back(temp);
}
return Packet;
}

namespace Packets
{
namespace Types
{
typedef const sf::Uint8 PacketType;

PacketType Welcome=0x10; //Client wants to join server
PacketType Welcome_Accept=0x11; //Server accepts the user
PacketType Welcome_Decline=0x12; //Server is full

PacketType Ping=0x20; //Server pings
PacketType Pong=0x21; //Client pongs

PacketType New_User=0x30; //User joins server
PacketType Delete_User=0x31; //Server removes user from list

PacketType Status_Update=0x40;

PacketType Quit=0xFF; //User quits app
} //Namespace types
namespace Structs
{
struct New_User
{
sf::Uint8 UserId;
std::string IpAdress;
std::string Nick;
};


struct Welcome
{
bool ShowIp;
std::string Nick;
};
struct Welcome_Accept
{
sf::Uint8 UserId;
std::vector<New_User> UserList;
};


struct Delete_User
{
sf::Uint8 UserId;
};


struct Status_Update_List
{
sf::Uint8 UserId;
sf::Uint16 X;
sf::Uint16 Y;
};
typedef std::vector<Status_Update_List> Status_Update;



sf::Packet& operator <<(sf::Packet& Packet, const New_User& A)
{
return Packet << A.UserId << A.IpAdress << A.Nick;
}
sf::Packet& operator >>(sf::Packet& Packet, New_User& A)
{
return Packet >> A.UserId >> A.IpAdress >> A.Nick;
}

sf::Packet& operator <<(sf::Packet& Packet, const Welcome& A)
{
return Packet << A.ShowIp << A.Nick;
}
sf::Packet& operator >>(sf::Packet& Packet, Welcome& A)
{
return Packet >> A.ShowIp >> A.Nick;
}

sf::Packet& operator <<(sf::Packet& Packet, const Welcome_Accept& A)
{
return Packet << A.UserId << A.UserList;
}
sf::Packet& operator >>(sf::Packet& Packet, Welcome_Accept& A)
{
return Packet >> A.UserId >> A.UserList;
}

sf::Packet& operator <<(sf::Packet& Packet, const Delete_User& A)
{
return Packet << A.UserId;
}
sf::Packet& operator >>(sf::Packet& Packet, Delete_User& A)
{
return Packet >> A.UserId;
}

sf::Packet& operator <<(sf::Packet& Packet, const Status_Update_List& A)
{
return Packet << A.UserId << A.X << A.Y;
}
sf::Packet& operator >>(sf::Packet& Packet, Status_Update_List& A)
{
return Packet >> A.UserId >> A.X >> A.Y;
}
} //Namespace structs
} //Namespace packets


Code: [Select]

//Main.cpp
#include "PacketTypes.h"

int main()
{
}


And the error
Code: [Select]

1>c:\documents and settings\ritave\moje dokumenty\visual studio 2008\projects\pointertest\pointertest\PacketTypes.h(112) : error C2678: binary '<<' : no operator found which takes a left-hand operand of type 'sf::Packet' (or there is no acceptable conversion)
1>        C:\Program Files\Microsoft Visual Studio 9.0\VC\include\SFML/Network/IPAddress.hpp(226): could be 'std::ostream &sf::operator <<(std::ostream &,const sf::IPAddress &)' [found using argument-dependent lookup]
1>        c:\documents and settings\ritave\moje dokumenty\visual studio 2008\projects\pointertest\pointertest\PacketTypes.h(92): or       'sf::Packet &Packets::Structs::operator <<(sf::Packet &,const Packets::Structs::New_User &)'
1>        c:\documents and settings\ritave\moje dokumenty\visual studio 2008\projects\pointertest\pointertest\PacketTypes.h(101): or       'sf::Packet &Packets::Structs::operator <<(sf::Packet &,const Packets::Structs::Welcome &)'
1>        c:\documents and settings\ritave\moje dokumenty\visual studio 2008\projects\pointertest\pointertest\PacketTypes.h(110): or       'sf::Packet &Packets::Structs::operator <<(sf::Packet &,const Packets::Structs::Welcome_Accept &)'
1>        C:\Program Files\Microsoft Visual Studio 9.0\VC\include\SFML/Network/Packet.hpp(128): or       'sf::Packet &sf::Packet::operator <<(bool)'
1>        C:\Program Files\Microsoft Visual Studio 9.0\VC\include\SFML/Network/Packet.hpp(129): or       'sf::Packet &sf::Packet::operator <<(sf::Int8)'
1>        C:\Program Files\Microsoft Visual Studio 9.0\VC\include\SFML/Network/Packet.hpp(130): or       'sf::Packet &sf::Packet::operator <<(sf::Uint8)'
1>        C:\Program Files\Microsoft Visual Studio 9.0\VC\include\SFML/Network/Packet.hpp(131): or       'sf::Packet &sf::Packet::operator <<(sf::Int16)'
1>        C:\Program Files\Microsoft Visual Studio 9.0\VC\include\SFML/Network/Packet.hpp(132): or       'sf::Packet &sf::Packet::operator <<(sf::Uint16)'
1>        C:\Program Files\Microsoft Visual Studio 9.0\VC\include\SFML/Network/Packet.hpp(133): or       'sf::Packet &sf::Packet::operator <<(sf::Int32)'
1>        C:\Program Files\Microsoft Visual Studio 9.0\VC\include\SFML/Network/Packet.hpp(134): or       'sf::Packet &sf::Packet::operator <<(sf::Uint32)'
1>        C:\Program Files\Microsoft Visual Studio 9.0\VC\include\SFML/Network/Packet.hpp(135): or       'sf::Packet &sf::Packet::operator <<(float)'
1>        C:\Program Files\Microsoft Visual Studio 9.0\VC\include\SFML/Network/Packet.hpp(136): or       'sf::Packet &sf::Packet::operator <<(double)'
1>        C:\Program Files\Microsoft Visual Studio 9.0\VC\include\SFML/Network/Packet.hpp(137): or       'sf::Packet &sf::Packet::operator <<(const char *)'
1>        C:\Program Files\Microsoft Visual Studio 9.0\VC\include\SFML/Network/Packet.hpp(138): or       'sf::Packet &sf::Packet::operator <<(const std::string &)'
1>        C:\Program Files\Microsoft Visual Studio 9.0\VC\include\SFML/Network/Packet.hpp(139): or       'sf::Packet &sf::Packet::operator <<(const wchar_t *)'
1>        C:\Program Files\Microsoft Visual Studio 9.0\VC\include\SFML/Network/Packet.hpp(140): or       'sf::Packet &sf::Packet::operator <<(const std::wstring &)'
1>        while trying to match the argument list '(sf::Packet, const std::vector<_Ty>)'
1>        with
1>        [
1>            _Ty=Packets::Structs::New_User
1>        ]
1>c:\documents and settings\ritave\moje dokumenty\visual studio 2008\projects\pointertest\pointertest\PacketTypes.h(116) : error C2678: binary '>>' : no operator found which takes a left-hand operand of type 'sf::Packet' (or there is no acceptable conversion)
1>        C:\Program Files\Microsoft Visual Studio 9.0\VC\include\SFML/Network/IPAddress.hpp(215): could be 'std::istream &sf::operator >>(std::istream &,sf::IPAddress &)' [found using argument-dependent lookup]
1>        c:\documents and settings\ritave\moje dokumenty\visual studio 2008\projects\pointertest\pointertest\PacketTypes.h(96): or       'sf::Packet &Packets::Structs::operator >>(sf::Packet &,Packets::Structs::New_User &)'
1>        c:\documents and settings\ritave\moje dokumenty\visual studio 2008\projects\pointertest\pointertest\PacketTypes.h(105): or       'sf::Packet &Packets::Structs::operator >>(sf::Packet &,Packets::Structs::Welcome &)'
1>        c:\documents and settings\ritave\moje dokumenty\visual studio 2008\projects\pointertest\pointertest\PacketTypes.h(114): or       'sf::Packet &Packets::Structs::operator >>(sf::Packet &,Packets::Structs::Welcome_Accept &)'
1>        C:\Program Files\Microsoft Visual Studio 9.0\VC\include\SFML/Network/Packet.hpp(110): or       'sf::Packet &sf::Packet::operator >>(bool &)'
1>        C:\Program Files\Microsoft Visual Studio 9.0\VC\include\SFML/Network/Packet.hpp(111): or       'sf::Packet &sf::Packet::operator >>(sf::Int8 &)'
1>        C:\Program Files\Microsoft Visual Studio 9.0\VC\include\SFML/Network/Packet.hpp(112): or       'sf::Packet &sf::Packet::operator >>(sf::Uint8 &)'
1>        C:\Program Files\Microsoft Visual Studio 9.0\VC\include\SFML/Network/Packet.hpp(113): or       'sf::Packet &sf::Packet::operator >>(sf::Int16 &)'
1>        C:\Program Files\Microsoft Visual Studio 9.0\VC\include\SFML/Network/Packet.hpp(114): or       'sf::Packet &sf::Packet::operator >>(sf::Uint16 &)'
1>        C:\Program Files\Microsoft Visual Studio 9.0\VC\include\SFML/Network/Packet.hpp(115): or       'sf::Packet &sf::Packet::operator >>(sf::Int32 &)'
1>        C:\Program Files\Microsoft Visual Studio 9.0\VC\include\SFML/Network/Packet.hpp(116): or       'sf::Packet &sf::Packet::operator >>(sf::Uint32 &)'
1>        C:\Program Files\Microsoft Visual Studio 9.0\VC\include\SFML/Network/Packet.hpp(117): or       'sf::Packet &sf::Packet::operator >>(float &)'
1>        C:\Program Files\Microsoft Visual Studio 9.0\VC\include\SFML/Network/Packet.hpp(118): or       'sf::Packet &sf::Packet::operator >>(double &)'
1>        C:\Program Files\Microsoft Visual Studio 9.0\VC\include\SFML/Network/Packet.hpp(119): or       'sf::Packet &sf::Packet::operator >>(char *)'
1>        C:\Program Files\Microsoft Visual Studio 9.0\VC\include\SFML/Network/Packet.hpp(120): or       'sf::Packet &sf::Packet::operator >>(std::string &)'
1>        C:\Program Files\Microsoft Visual Studio 9.0\VC\include\SFML/Network/Packet.hpp(121): or       'sf::Packet &sf::Packet::operator >>(wchar_t *)'
1>        C:\Program Files\Microsoft Visual Studio 9.0\VC\include\SFML/Network/Packet.hpp(122): or       'sf::Packet &sf::Packet::operator >>(std::wstring &)'
1>        while trying to match the argument list '(sf::Packet, std::vector<_Ty>)'
1>        with
1>        [
1>            _Ty=Packets::Structs::New_User
1>        ]

The error lines are in code from previous post, in calling snippet (the return lines)

That's my whole project, Visual C++ Empty Project, SFML dynamic, preprocessor macro is done, and sfml-system.lib and sfml-network.lib are included

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Packets and vector?
« Reply #3 on: December 30, 2009, 06:01:40 pm »
Hi

Your problem is related with the use of namespaces. I don't know the exact C++ rule here, but anyway putting your operator >> and << overloads outside namespaces solves the problem.
Laurent Gomila - SFML developer

ritave

  • Newbie
  • *
  • Posts: 26
    • View Profile
Packets and vector?
« Reply #4 on: December 30, 2009, 06:09:14 pm »
:shock: Oh wow, I've done real life facepunch, thanks a lot - now it's working!

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Packets and vector?
« Reply #5 on: December 30, 2009, 08:54:17 pm »
If the operator is in the same namespace as one of its operands, the compiler can apply ADL (argument dependent lookup) and find the operator. Since that condition isn't met in your example, your operator isn't considered for ADL.

By the way, this isn't operator-specific, dependent name lookup is a concept that works for all free functions. The difference is that you can't specify namespaces for infix operators such as Packets::Structs::<<.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

 

anything