2015-10-22 23 views
6

Mam makro, które używam dużo, zainspirowany innym pytaniem:Przepisywanie C++ makro jako funkcję itp

#define to_string(x) dynamic_cast<ostringstream &> ((ostringstream() << setprecision(4) << dec << x)).str() 

ten jest niezwykle przydatny na przykład w użyciu funkcje biorąc wejść ciąg:

some_function(to_string("The int is " << my_int)); 

Jednak powiedziano mi, że używanie makr w C++ to zła praktyka i faktycznie miałem problemy z powyższym działaniem na różnych kompilatorach. Czy istnieje sposób, aby napisać to jako inną konstrukcję, np. funkcja, w której będzie miała taką samą wszechstronność?

+3

'std :: to_string'? – Downvoter

Odpowiedz

6

W C++ 11 i nowszym mamy teraz std::to_string. Możemy użyć tego do przekonwertowania danych na ciąg i dopisać go do tego, co chcemy.

some_function("The int is " + std::to_string(my_int)); 
+0

Dzięki! Ale czy muszę napisać to tak, jak powyżej? To trochę bardziej nieporządne niż oryginalne makro i musiałbym przepisać całkiem sporo kodu. – jorgen

+1

@jorgen tak. To nie jest bezpośredni zamiennik. Sposób, w jaki masz go z makr jest jedynym sposobem, w jaki widziałem to zrobić bez przepisywania kodu jak wyżej. – NathanOliver

2

Jak na ironię, tutaj jest to to_string.

Zamiast: to_string("The int is " << my_int)

Można napisać: "The int is " + to_string(my_int)

ta zwróci string.

[Live Example]

7

makra ma więcej możliwości niż std::to_string ofert. Akceptuje każdą sensowną sekwencję operatorów <<, ustawia domyślną dokładność i podstawę dziesiętną. Kompatybilny sposobem jest stworzenie std::ostringstream owijki, który jest niejawnie zamienny do std::string:

class Stringify { 
    public: 
     Stringify() : s() { s << std::setprecision(4) << std::dec; }; 

     template<class T> 
     Stringify& operator<<(T t) { s << t; return *this; } 

     operator std::string() { return s.str(); } 
    private: 
     std::ostringstream s; 
}; 

void foo(std::string s) { 
    std::cout << s << std::endl; 
} 

int main() 
{ 
    foo(Stringify() << "This is " << 2 << " and " << 3 << " and we can even use manipulators: " << std::setprecision(2) << 3.1234); 
} 

żywo: http://coliru.stacked-crooked.com/a/14515cabae729875