Reputation: 381
I don't use C++11 yet, so I wrote the functions to_string(whatever)
by myself. They should only be compiled if they don't exist. If I switch to C++11, they should be skipped. I have something like this:
#ifndef to_string
string to_string(int a){
string ret;
stringstream b;
b << a;
b >> ret;
return ret;
}
string to_string(double a){
string ret;
stringstream b;
b << a;
b >> ret;
return ret;
}
#endif
This doesn't work apparently. Is something like this possible and if yes, how?
Upvotes: 18
Views: 6307
Reputation: 13988
You could play with SFINAE having in mind that non-template overloads are preferred over the template ones. This compiles in both pre-c++11 and c++11:
#include <sstream>
#include <string>
#include <iostream>
using namespace std;
namespace my {
template <bool V, class T>
struct enable_if {
};
template <class T>
struct enable_if<true, T> {
typedef T type;
};
template <class T1, class T2>
struct is_same {
static const bool value = false;
};
template <class T>
struct is_same<T, T> {
static const bool value = true;
};
}
template <class T>
typename my::enable_if<my::is_same<T, int>::value
|| my::is_same<T, double>::value, string>::type
to_string(T const& a) {
string ret;
stringstream b;
b << a;
b >> ret;
return ret;
}
int main() {
cout << to_string(2) << endl;
cout << to_string(3.4) << endl;
}
Upvotes: 2
Reputation: 11787
You can put your functions inside a macro, like this:
#ifndef to_string
#define to_string
//....
#endif
Then, in another file, write this:
#if __cplusplus >= 201103L
#undef to_string
#else
#define to_string
#endif
Upvotes: 1
Reputation: 9735
This is one of main purpose of namespace
existence.
My suggest is to include your personal function in a proper namespace, something like:
namespace myns {
std::string to_string(...) {
// ...
}
// etc...
}
This is fundamental in order to avoid future conflict problems.
Afterwards, when you're going to use that function, you can simple select the proper function with a MACRO
substitution.
Something like:
#if (__cplusplus >= 201103L)
#define my_tostring(X) std::to_string(X)
#else
#define my_tostring(X) myns::to_string(X)
#endif
Note __cplusplus
is a pre-defined macro which contains compiling information about standard version.
Edit:
Something less "violent", it will select the proper namespace for that specific function in accordance with the standard version:
#if (__cplusplus >= 201103L)
using std::to_string;
#else
using myns::to_string;
#endif
// ... somewhere
to_string(/*...*/); // it should use the proper namespace
Upvotes: 14
Reputation: 1
Boost.Config has some macros to check whether C++11 features are supported/used.
Upvotes: 0