1

I am pretty new to C++, and I am having an error with the CL_String8 function in ClanLib.

When I try to compile:

CL_String now() {
    CL_DateTime now = CL_DateTime::get_current_local_time();
    return CL_String8(now.get_hour()) + " " + CL_String8(now.get_minutes()) + " " + CL_String8(now.get_seconds());
}

I get this error (repeated 3 times):

src/utils.cpp: In function ‘CL_String now()’:
src/utils.cpp:15:34: error: call of overloaded ‘CL_String8(unsigned char)’ is ambiguous
src/utils.cpp:15:34: note: candidates are:
/usr/include/ClanLib-2.3/ClanLib/Core/Text/string8.h:74:2: note: CL_String8::CL_String8(const wchar_t*) <near match>
/usr/include/ClanLib-2.3/ClanLib/Core/Text/string8.h:74:2: note:   no known conversion for argument 1 from ‘unsigned char’ to ‘const wchar_t*’
/usr/include/ClanLib-2.3/ClanLib/Core/Text/string8.h:63:2: note: CL_String8::CL_String8(const char*) <near match>
/usr/include/ClanLib-2.3/ClanLib/Core/Text/string8.h:63:2: note:   no known conversion for argument 1 from ‘unsigned char’ to ‘const char*’
/usr/include/ClanLib-2.3/ClanLib/Core/Text/string8.h:55:2: note: CL_String8::CL_String8(const CL_String8&) <near match>
/usr/include/ClanLib-2.3/ClanLib/Core/Text/string8.h:55:2: note:   no known conversion for argument 1 from ‘unsigned char’ to ‘const CL_String8&’
/usr/include/ClanLib-2.3/ClanLib/Core/Text/string8.h:50:2: note: CL_String8::CL_String8(const string&) <near match>
/usr/include/ClanLib-2.3/ClanLib/Core/Text/string8.h:50:2: note:   no known conversion for argument 1 from ‘unsigned char’ to ‘const string& {aka const std::basic_string<char>&}’

How can I define which one of the functions I want to use?

tehtros
  • 179
  • 7
  • Also, if there are any opinions, which of the "" should I use? – tehtros Sep 17 '12 at 18:45
  • 1
    I don't know about ClanLib, however as it seems you're passing a single character or numerical value. That's why it can't 'determine which function you want to call.' The problem seems to be in the return value of now.get_something...what do those return? What datatype I mean. – ATaylor Sep 17 '12 at 18:46
  • unsigned char get_hour() const; – tehtros Sep 17 '12 at 18:49
  • I'm kind of confused why the return types of those are single characters. What do they print if you print the hour, minute, and second? – chris Sep 17 '12 at 18:50
  • 1
    @chris If I get that right, they are numerical representations. An unsigned character can range from 0-255, which is more than sufficient for all those examples, since hours: 0-23, minutes and seconds: 0-59 – ATaylor Sep 17 '12 at 18:54
  • @ATaylor, `uint8_t` would be a more fitting choice then. – chris Sep 17 '12 at 18:56
  • @chris Well, that's the problem...uint8_t technically IS an unsigned character. Whenever I see uint8_t it's a typedef for unsigned character. After all, it's only a value range specifier (bit width). – ATaylor Sep 17 '12 at 18:58
  • @ATaylor, Yes, my point was that `uint8_t` makes it clear you're returning a limited-range integer, rather than a character. – chris Sep 17 '12 at 19:07
  • @chris Yes, I know. That's why it's a typedef ;) – ATaylor Sep 17 '12 at 19:11

3 Answers3

2

According to documentation, the functions 'get_hour()', etc. return a single unsigned character, which in turn means, that none of the function templates match your call.

It's like the function is made for apples, cherries or bananas, and you're giving it pears.

To solve your problem, I suggest to either use the C-Function 'sprintf', and run THAT through the CL_String8-Function...or use std::string.

Solution using sprintf:

#include <stdio.h>
char Buffer[50];
sprintf(Buffer, "%02d %02d %02d", now.get_hour(), now.get_minutes(), now.get_seconds());
return CL_String8(Buffer);

This will return the data in the format hh:mm:ss, with 0 for all values lower than 9.

ATaylor
  • 2,598
  • 2
  • 17
  • 25
  • The first part seems to be a much better, faster solution than mine. +1 – user123 Sep 17 '12 at 18:54
  • Thank you, though you need to be careful, since it does no conversions. It would probably print the character equivalents of the values. The second one is rather failproof in that regard. – ATaylor Sep 17 '12 at 18:56
  • First solution gives me `src/utils.cpp:17:75: error: invalid operands of types ‘const char*’ and ‘const char [2]’ to binary ‘operator+’` I am trying the second solution now. – tehtros Sep 17 '12 at 18:57
  • @tehtros Meh...std::strings, I'm telling you. Don't worry, sprintf has never failed me in that regard. You may need stdio.h or stdlib.h for that one. – ATaylor Sep 17 '12 at 19:01
  • It worked like a charm! Thank you! Now, my only problem is that if it's only a single digit, it looks a little weird, (ex. `15:3:1`) but that's a question for another time. – tehtros Sep 17 '12 at 19:02
  • 1
    @tehtros You're welcome, and if you want it to be two digits each try %02d %02d %02d. That will add a zero, if it's only one digit. – ATaylor Sep 17 '12 at 19:12
  • @ATaylor Thanks for the tip! In all honesty, after looking through the documentation a little, I ended up using this: `return cl_format("%1:%2:%3", now.get_hour(), now.get_minutes(), now.get_seconds());` However, I might switch back to yours to use the %02d thing! – tehtros Sep 17 '12 at 20:37
2

ClanLib has a formatting function you can use to avoid low-level C formatting code:

CL_DateTime now = CL_DateTime::get_current_local_time();
return cl_format("%1 %2 %3", now.get_hour(), now.get_minutes(), now.get_seconds());

cl_format accepts most basic types automatically.

Secondly, CL_DateTime has a to_long_time_string() that returns the time as hh:mm:ss, so you could use that unless you need your specific formatting:

return now.to_long_time_string();

Third, there is no need to use CL_String8 directly. Depending on unicode compilation settings CL_String will either use CL_String8 or CL_String16 internally. CL_String8 is not something you need to use explicitly in your code.

SingerOfTheFall
  • 29,228
  • 8
  • 68
  • 105
sphair
  • 1,674
  • 15
  • 29
1

now.get_minutes() and the like are rerturning unsigned chars, and I'm sure that CL_String8 does not have any overloaded version that takes such a parameter.

Pass your values to this function before passing them to CL_String8

#include <sstream>
#include <string> // not sure if necessary

const char* unsignedChar2string(unsigned char c) {
    stringstream stream;
    stream << static_cast<char>(c); // I'm not 100% sure if the cast is necessary
                                    // I'm also not sure whether it should be static, dynamic, or reinterpret.
    return stream.str().c_str();
}
user123
  • 8,970
  • 2
  • 31
  • 52
  • Meh, my solution sucks as it requires you to include sstream into your application thus increasing filesize for no reason. (Unless you already included it) – user123 Sep 17 '12 at 18:58
  • 2
    Your solution is just a different perspective. It's not necessarily bad just because it increases the file size a bit. I just thought you might enjoy reading this: http://stackoverflow.com/questions/332030/when-should-static-cast-dynamic-cast-and-reinterpret-cast-be-used – chris Sep 17 '12 at 19:09