Reputation: 1508
I'm making a server interface for network programming and I ran into a problem. I want to make a server object uncopyable, mostly because it doesn't really make sense to do so and would probably make problems, and also because it uses threads which can't be copied. However, when I make the copy constructor and assignment operator private, I get an error:
Error 2 error C2248: '(namespaces..)::Server::Server' : cannot access private member declared in class '(namespaces..)::Server' (path..)\type_traits 1545 1 Server
The error seems to be in the type_traits
file? I haven't used it at all, though it might be possible that some of the other std
files I'm including use it? I'm using iostream, sstream, string, thread, map
.
Here's the server class definition:
class DLL_PUBLIC Server
{
public:
Server(unsigned int);
~Server();
(...)
private:
class PvtImpl; //Private implementation, so it isn't seen in the header file
PvtImpl *pvtImpl;
Server(const Server &par_other){}
Server& operator=(const Server &par_other){ return *this; }
(...)
};
and the private implementation:
class Server::PvtImpl
{
public:
bool running;
unsigned int port, backlog, currentlyConnected;
SOCKET listenSocket;
std::thread *acceptConnectionsThread;
std::thread* *receiveDataThreads; //I am using pointers instead of vectors because I want it to be fixed
ClientObj* *clients;
std::map<ClientObj*, unsigned int> clientIndexMap;
};
Since I don't know what code to post because I don't even know where the error is coming from, then tell me if you need a specific part of it posted. If I comment out the private copy constructor and assignment operator then it works, but I don't want this to be copyable and especially not through default constructor. Doubt it, but does it have something to do with it being a DLL?
Anyway that's it, thanks for your time
Update
So I added a = delete
to the constructor as suggested, and also made it public:
class DLL_PUBLIC Server
{
public:
Server(unsigned int);
Server(const Server &par_other) = delete;
~Server();
Server& operator=(const Server &par_other) = delete;
(...)
};
I am getting a bit of a different error now, but also in the type_traits file:
Error 2 error C2280: '(namespaces..)::Server::Server(const (namespaces..)::Server &)' : attempting to reference a deleted function (path..)\type_traits 1545 1 Server
A bit of code it is complaining about in that file:
// TEMPLATE FUNCTION _Decay_copy
template<class _Ty> inline
typename decay<_Ty>::type _Decay_copy(_Ty&& _Arg)
{ // forward _Arg as value of decayed type
return (_STD forward<_Ty>(_Arg));
}
_STD_END
Update 2
So this is the output window from VS as requested:
1>(path...)\type_traits(1545): error C2280: '(namespaces..)::Server::Server(const (namespaces..)::Server &)' : attempting to reference a deleted function
1> (path..)\Server.h(19) : see declaration of '(namespaces..)::Server::Server'
1> (path..)\thread(47) : see reference to function template instantiation '(namespaces..)::Server std::_Decay_copy<(namespaces..)::Server&>(_Ty)' being compiled
1> with
1> [
1> _Ty=(namespaces..)::Server &
1> ]
1> Server.cpp(94) : see reference to function template instantiation 'std::thread::thread<void(__cdecl &)(const (namespaces..)::Server &),(namespaces..)::Server&>(_Fn,(namespaces..)::Server &)' being compiled
1> with
1> [
1> _Fn=void (__cdecl &)(const (namespaces..)::Server &)
1> ]
The line 19 in the Server.h
it's mentioning is the copy constructor declaration. Line 94 in Server.cpp
is thread creation:
pvtImpl->acceptConnectionsThread = new std::thread(acceptConnections, *this);
The acceptConnections
function takes the server by constant reference so it shouldn't copy, here's the declaration:
friend void acceptConnections(const Server&);
Upvotes: 0
Views: 229
Reputation: 2554
Your problem is most likely in the thread constructor:
pvtImpl->acceptConnectionsThread = new std::thread(acceptConnections, *this);
Try this instead:
pvtImpl->acceptConnectionsThread = new std::thread(acceptConnections, std::ref(*this));
because without the std::ref() wrapper, a copy of your server instance will be passed into the thread constructor, which in turn will pass that copy by reference to your acceptConnections() method. Or at least try to, but it never got that far, as the compiler failed the initial copy.
Upvotes: 4