2015-10-07 18 views
7

Załóżmy, że mamCzy istnieje sposób, aby sprawdzić, czy wartości nie numerycznej makro

#define Name Joe 

Czy istnieje sposób, aby odróżnić różne wartości dla makra. Poniższa nie działa, ale masz pomysł

#if Name==Joe 
// some code 
#elif Name==Ben 
// some alternative code 
#endif 

chcę wykorzystać do różnych plików generowanych obiektów z tego samego kodu źródłowego. Źródło różni się tylko nieznacznie, więc można je łatwo kontrolować za pomocą makr. Makro należy przekazać za pomocą flagi kompilatora -DName=Joe. Należy również zauważyć, że Name będzie rzeczywista nazwa symbol, więc nie możemy używać sztuczek opartych na #define Joe 1 itp


przymusowej edit Zauważ, że this similar question faktycznie zajmuje makr ciąg wycenione. Co więcej, odpowiedzi tam nie pomagają. Przyjęta odpowiedź pozwala uniknąć problemu (ale go nie rozwiązuje), inna odpowiedź używa strcmp w makrach, które bazują na rozszerzeniu, itp.

+1

Czy funkcja nie działa? Jaki jest w tym przypadek? – NathanOliver

+3

Prawdopodobnie nie chcesz tego (problem XY) –

+0

@NathanOliver zobacz edycję – Walter

Odpowiedz

12

Tak, jest to możliwe, ale nie jest aż tak piękne.

Oto przykład; zmień NAME i wydrukuje poprawną rzecz. Po prostu musisz zdefiniować TEST_FOR_Name przed każdą nazwą, nadając każdej z nich unikalną wartość.

#define TEST_FOR_Joe 1 
#define TEST_FOR_Ben 2 
#define DO_TEST(NAME1, NAME2) DO_TEST_impl(NAME1, NAME2) 
#define DO_TEST_impl(NAME1, NAME2) TEST_FOR_ ## NAME1 == TEST_FOR_ ## NAME2 

#define NAME Ben 

#include <iostream> 

int main() { 
    std::cout << "Hello!" << std::endl; 
#if DO_TEST(NAME, Joe) 
    std::cout << "Joe Found!" << std::endl; 
#elif DO_TEST(NAME, Ben) 
    std::cout << "Ben Found!" << std::endl; 
#else 
    std::cout << "Neither found!" << std::endl; 
#endif 
} 

Podstawową ideą jest to, że budujemy tokeny z unikalnymi wartościami numerycznymi związanymi z każdą nazwą. Jeśli nie może znaleźć wartości tokenu, porównanie po prostu się nie powiedzie, ale poza tym upewnia się, że liczby są takie same.

+2

@sergej: Wyobraź sobie, że 'Joe' i' Ben' są typami: 'NAZWA var = {3};'. Nie działa, jeśli '#define NAME Joe' –

+2

@sergej: Zakładasz, że' Joe' i 'Ben' mogą być zdefiniowane jako liczby arbitralne.Jeśli symbole te mają znaczenie lub są już makrami, twoja prostsza metoda nie działa. Metoda Charlesa działa niezależnie. –

+0

Czy to nadal działa z nazwami makr określonymi przez opcję kompilatora '-DName = Joe'? – Walter

-1

Na pewno okaże się, że nie można w ciągu zaledwie C++ są niektóre sposoby, które znalazły rozszerzenia narzędzi do toolchain, ale nie są przenośne. Inny użytkownik pytający o coś podobnego: Here

+0

który nie jest przenośny ... – Walter

+0

(uwaga: nie przesłałem ci skargi) – Walter

+0

Ja też nie, ale "rozszerzenie toolchain" w niezaakceptowanej odpowiedzi na połączone pytanie to fantazja. Zobacz trzeci komentarz do tej odpowiedzi, aby uzyskać wyjaśnienie. – rici