Скажем, мы проигнорируем очевидные вещи как защита заголовка.
Иногда, Вы хотите генерировать код, который должен быть, копируют/вставляют предварительным компилятором:
#define RAISE_ERROR_STL(p_strMessage) \
do \
{ \
try \
{ \
std::tstringstream strBuffer ; \
strBuffer << p_strMessage ; \
strMessage = strBuffer.str() ; \
raiseSomeAlert(__FILE__, __FUNCSIG__, __LINE__, strBuffer.str().c_str()) \
} \
catch(...){} \
{ \
} \
} \
while(false)
, который позволяет Вам кодировать это:
RAISE_ERROR_STL("Hello... The following values " << i << " and " << j << " are wrong") ;
И может генерировать сообщения как:
Error Raised:
====================================
File : MyFile.cpp, line 225
Function : MyFunction(int, double)
Message : "Hello... The following values 23 and 12 are wrong"
Примечание, которое смешивание шаблонов с макросами может привести к еще лучшим результатам (т.е. автоматически генерация значений бок о бок с их именами переменной)
Другие времена, Вам нужно __ ФАЙЛ __ и/или __ СТРОКА __ некоторого кода, для генерации информации об отладке, например. Следующее является классиком для Visual C++:
#define WRNG_PRIVATE_STR2(z) #z
#define WRNG_PRIVATE_STR1(x) WRNG_PRIVATE_STR2(x)
#define WRNG __FILE__ "("WRNG_PRIVATE_STR1(__LINE__)") : ------------ : "
Как со следующим кодом:
#pragma message(WRNG "Hello World")
это генерирует сообщения как:
C:\my_project\my_cpp_file.cpp (225) : ------------ Hello World
Другие времена, необходимо генерировать код с помощью # и ## операторов конкатенации, как генерация методов get и методов set для свойства (это для вполне ограниченные случаи, через).
Другие времена, Вы генерируете код, чем не скомпилирует, если используется через функцию, как:
#define MY_TRY try{
#define MY_CATCH } catch(...) {
#define MY_END_TRY }
, Который может использоваться в качестве [1 122]
MY_TRY
doSomethingDangerous() ;
MY_CATCH
tryToRecoverEvenWithoutMeaningfullInfo() ;
damnThoseMacros() ;
MY_END_TRY
(все еще, я только видел, этот вид кода справедливо использовал однажды )
наконец, что не менее важно, известное boost::foreach
!!!
#include
#include
#include
int main()
{
std::string hello( "Hello, world!" );
BOOST_FOREACH( char ch, hello )
{
std::cout << ch;
}
return 0;
}
(Примечание: код копирует/вставляет с домашней страницы повышения)
, Который является (по моему скромному мнению), путем лучше, чем [1 110].
Так, макросы всегда полезны, потому что они вне нормальных правил компилятора. Но я нахожу, что большинство время, которое я вижу один, они - эффективно остатки C код, никогда не переводимый в надлежащий C++.
Самоцвет GeoKit звучит как нельзя лучше для того, что вы хотите сделать.
Он абстрагирует интерфейсы к различным сервисам геокодирования (Yahoo, Google и т. Д.) И предоставляет код для расчета расстояний.
Вы можете геокодировать почтовые индексы, чтобы получить местоположение, получить доступ к адресной информации о местоположении и вычислить расстояния между
Вот краткое руководство, бесстыдно скопированное со связанной страницы, просто чтобы дать вам представление о том, как работает библиотека:
irb> require 'rubygems'
irb> require 'geokit'
irb> a=Geokit::Geocoders::YahooGeocoder.geocode '140 Market St, San Francisco, CA'
irb> a.ll
=> 37.79363,-122.396116
irb> b=Geokit::Geocoders::YahooGeocoder.geocode '789 Geary St, San Francisco, CA'
irb> b.ll
=> 37.786217,-122.41619
irb> a.distance_to(b)
=> 1.21120007413626
irb> a.heading_to(b)
=> 244.959832435678
irb(main):006:0> c=a.midpoint_to(b) # what's halfway from a to b?
irb> c.ll
=> "37.7899239257175,-122.406153503469"
irb(main):008:0> d=c.endpoint(90,10) # what's 10 miles to the east of c?
irb> d.ll
=> "37.7897825005142,-122.223214776155"