TCP Client Send

I have a class that I wrote (TCPClient). The constructor creates a SOCKET and connects correctly, everything is good here. I then have a function called send:

int TCPClient::send(char* buff) {
...
iResult = send(client, buff, len, 0);
...
}

In here, Visual Studio complains that "send" does not take 4 parameters (clearly I want to call the WinSock2 send from here but there's a namespace conflict. I can't seem to find which namespace contains the send I want. Also, I would have thought that the compiler would be smart enough to realize these aren't the same functions because of the different number of command line arguments. If I rename my TCPClient::send function then everything works. Anyone know why this is happening?
The WinSock2 send() function is in the global namespace, which doesn't have a name. You need to use the scope resolution operator -- operator:: -- without a scope name.

1
2
3
4
5
int TCPClient::send(char* buff) {
    ...
    iResult = ::send(client, buff, len, 0); // I mean the global function, not this method!
    ...
}


Unfortunately, the namespace resolution mechanism isn't that smart. The method name is hiding the global one, so you either have to use the scope resolution operator as above, or use a using statement to re-expose the global function within the scope of the method.

1
2
3
4
5
6
7
8
9
10
11
void print(const char* prefix, int i) {
	cout << prefix << i << endl;
}

class Example {
public:
	void print(int i) {
		using ::print;
		print("int = " , i);
	}
}; 


(I'd stick to the previous form...)

While I know it's an interaction between overloads and scopes, I don't know the rules in detail. But I do know that a similar thing can happen when a derived class defines a method with the same name as one of the base class methods but with a different signature.

For this toy program

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
using namespace std;

class Example {
public:
	void print(int i) {
		cout << "int = " << i << endl;
	}
};

class Derived : public Example {
public:
	void print(bool b) {
		cout << "bool = " << boolalpha << b << endl;
	}
};

int main() {
	Derived d;
	d.print(true);
	d.print(3);
	return 0;
}


The method print in Derived hides the one in Example and so:

(a) I get a warning when I compile (in this case, with VC++2008)

warning C4305: 'argument' : truncation from 'int' to 'bool'

(b) When I run the program, it uses the bool overload for both the bool and int values. :-(

bool = true
bool = true

Here, you either have to qualify the int overload

1
2
3
4
5
6
7
int main() {
	Derived d;
	d.print(true);
	d.Base::print(3); // ugly!

	return 0;
}


Or re-expose the base class method name with a using statement (this exposes all overloads of a method).

1
2
3
4
5
6
7
8
class Derived : public Base {
public:
	void print(bool b) {
		cout << "bool = " << boolalpha << b << endl;
	}

	using Base::print; // re-expose base class overload
};


Which works as hoped

bool = true
int = 3

But a using statement line using ::print; cannot be used to re-expose a global function within the scope of a class.

Andy
Last edited on
Topic archived. No new replies allowed.