tags:

views:

583

answers:

4

Below code is used to get a std::string representation from ASCII code.

string Helpers::GetStringFromASCII(const int asciiCode) const
{
    return string(1,char(asciiCode));
}

It works well. But in my application, I know the ASCII codes at compile time. So I will be calling it like

string str =  GetStringFromASCII(175) // I know 175 at compile time

Question

Is there any way to make the GetStringFromASCII method a template so that the processing happens at compile time and I can avoid calling the function each time at runtime.

Any thoughts?

A: 

How about something like this:

#include <iostream>
#include <string>

using namespace std;

template <int asciiCode>
inline string const &getStringFromASCII()
{
  static string s(1,char(asciiCode));
  return s;
}

int main(int, char const**) {
  cout << getStringFromASCII<65>() << endl;
}

EDIT: returns a ref now

Mr Fooz
You get practically zero performance benefit with this. The 'char' type casting still and happens at run time and so does the string constructor call.
Frederick
Thanks for the reply. Why you have used static? What's wrong in just returning the string?
Appu
In your code, I guess getStringFromASCII is not called always. Compiler will create specialization and use that, right?
Appu
Mr Fooz, well if you use static, then also make the function return a reference :) the static is a good idea, but having it still return the string by value will destroy that good idea i think
Johannes Schaub - litb
Mr Fooz
Making the string a function-scoped static variable also happens to make this version thread-unsafe: if multiple threads call the function simultaneously the first time it's called, they might initialize the string simultaneously, leaking memory.
bk1e
Also, note that declaring the function to be static is unrelated to declaring the variable to be static.
bk1e
yeah he should make his function inline instead of static to avoid multiple definitions error. static for functions is deprecated -.-
Johannes Schaub - litb
+3  A: 

Instead of feeding an int constant to a string conversion function, use a string constant directly:

string str("\xAF"); // 0xAF = 175

By the way, except for heavy performance needs in a loop, trading code readability for some CPU cycles is rarely money effective overall.

total
That looks simple. But as Frederick said, looks like I will not get any benefit here if I use templates.
Appu
Yes you are right, if you really want the performance gain, either usestatic const string STRING_175("\xAF");then reference the const variable, or useconst char* str = "\xAF"which will be casted to a std::string automatically if necessary
total
Actually - this is slower! It needs to do a strlen on "\xAF".
MSalters
MSalters, this code allocates from the free store, which will be much slower than doing strlen on a 2-byte string, and may have enough jitter to make the effect of the strlen unmeasurable.
bk1e
...unless the string implementation uses SSO (small string optimization), in which case constructing small strings is essentially free because it doesn't touch the free store, and in which case none of this matters performance-wise.
bk1e
Yeah all these optimisations mean nothing beside the string constructor as stated by Frederick. But again, if these cpu cycles are really needed, it would be better to allocate the string out of the loop or statically.
total
+4  A: 

This kind of template meta programming works well when you're dealing with primitive data types like ints and floats. If you necessarily need a string object, you can't avoid calling the std::string constructor and there's no way that call can happen at compile time. Also, I don't think you can drag the cast to char to compile time either, which, in all, means that templates cannot help you here.

Frederick
Thanks for the reply. Yeah I got that templates is not needed here.
Appu
A: 

Why are you even bothering with a helper function?

string s( 1, char(175) );

That's all you need and it's the quickest you're going to get.

Rob K