Определите функцию / метод, если не определено до переполнения стека

Я пока не использую C ++ 11, поэтому я написал функции to_string(whatever) сам. Они должны быть скомпилированы, только если они не существуют. Если я переключусь на C ++ 11, они должны быть пропущены. У меня есть что-то вроде этого:

#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

Это не работает, по-видимому. Возможно ли что-то подобное, и если да, то как?

13

Решение

Это одна из основных целей namespace существование.

Я предлагаю включить вашу личную функцию в правильное пространство имен, что-то вроде:

namespace myns {
std::string to_string(...) {
// ...
}
// etc...
}

Это имеет основополагающее значение для избежания проблем в будущем.

После этого, когда вы собираетесь использовать эту функцию, вы можете просто выбрать соответствующую функцию с помощью MACRO замена.

Что-то вроде:

#if (__cplusplus >= 201103L)
#define my_tostring(X) std::to_string(X)
#else
#define my_tostring(X) myns::to_string(X)
#endif

Заметка __cplusplus это предопределенный макрос который содержит компиляцию информации о стандартной версии.


Редактировать:
Что-то менее «жестокое», оно выберет правильное пространство имен для этой конкретной функции в соответствии со стандартной версией:

#if (__cplusplus >= 201103L)
using std::to_string;
#else
using myns::to_string;
#endif

// ... somewhere
to_string(/*...*/);  // it should use the proper namespace
14

Другие решения

Вы не можете проверить, определены ли они как таковые, но вы можете проверить языковую версию:

#if __cplusplus < 201103L

(Существует полезная коллекция предопределенных макросов компилятора Вот.)

9

Вы можете поиграть с SFINAE, имея в виду, что не шаблонные перегрузки предпочтительнее шаблонных. Это компилируется в pre-c ++ 11 и 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;
}
2

Вы можете поместить свои функции в макрос, например так:

#ifndef to_string
#define to_string

//....

#endif

Затем в другом файле напишите это:

#if __cplusplus >= 201103L
#undef to_string
#else
#define to_string
#endif
1

Boost.Config имеет некоторые макрос чтобы проверить, поддерживаются / используются ли функции C ++ 11.

0
По вопросам рекламы [email protected]