2

I'm working on a C++ project under GCC 4.8.1. I have two getter/setter pairs:

LOGFONT GetTitleBarFont();
void SetTitleBarFont(LOGFONT titleBarFont);

std::wstring GetTitleBarFont();
void SetTitleBarFont(std::wstring titleBarFont);

But for some reason, GCC is telling me these aren't valid overloads.

error: 'std::wstring GetTitleBarFont()' cannot be overloaded
error: with 'LOGFONT GetTitleBarFont()'

I don't understand what the issue here is. std::wstring is a STL type (std::basic_string<wchar_t> to be precise) with a host of template work behind the scenes. LOGFONT is a Windows data type ( http://msdn.microsoft.com/en-us/library/windows/desktop/dd145037(v=vs.85).aspx ) composed almost entirely of native C++ datatypes (LONGs, and BYTEs, with an oddball TCHAR array). How could these be ambiguous overloads?

cf-
  • 8,598
  • 9
  • 36
  • 58

3 Answers3

2

You can't overload methods based on return type, because overload resolution takes into account the function signature.

1.3.11 Signature

the information about a function that participates in overload resolution (13.3): its parameter-type-list (8.3.5) and, if the function is a class member, the cv-qualifiers (if any) on the function itself and the class in which the member function is declared. [...]

---edit---
To elaborate a bit more on the possible solutions, you can either

1) Change name of the getters:

std::wstring GetTitleBarFontWString();
LOGFONT GetTitleBarFontLogFont();

2) Have out parameters (this doesn't compose too well, but sometimes you have to)

void GetTitleBarFont(std::wstring& out);
void GetTitleBarFont(LOGFONT& out);

3) Abuse template specialization so caller can specify what he wants to get back. (GetTitleBarFont<std::wstring>, GetTitleBarFont<LOGFONT>)

Basically there isn't really good solution.

Full credits to chris for 3), partial for 2)

Xarn
  • 3,460
  • 1
  • 21
  • 43
  • 1
    Alternatively, have the user specify the type: `GetTitleBarFont()` or `GetTitleBarFont()`, or use a reference parameter: `GetTitleBar(someLOGFONT)` or `GetTitleBar(someWstring)` – chris Feb 07 '14 at 01:29
  • @Xam: _Basically there isn't really good solution_ - yes there is: Name the function properly. It doesn't return a font, but its *name*, name it `Get/SetTitleBarFontName` and there is no problem :) – Johann Gerell Feb 07 '14 at 09:10
  • @JohannGerell Details... ;-) Assuming he wants to keep the name same for whatever reason (ie. some template magic where he would want to call GetTitleBarFront and get the return type he wanted) there isn't, but yes, renaming the name getter to get name makes sense. – Xarn Feb 07 '14 at 10:05
1

Assuming that the string-returning function doesn't give a font, but a font name, the obvious solution is

std::wstring GetTitleBarFontName();
void SetTitleBarFontName(std::wstring titleBarFont);

since you cannot overload with only the return type as discriminator.

Johann Gerell
  • 24,991
  • 10
  • 72
  • 122
0

For anyone else who runs across this question and wonders, as I just did, why C++ doesn't take the return value into account when determining which overload to use: Function overloading by return type? is an incredibly detailed answer on why this is the case.

Community
  • 1
  • 1
cf-
  • 8,598
  • 9
  • 36
  • 58