2016-01-22 3 views
4

Я видел использование макросов #ifdef (пример Eigen library) для управления конкретной платформой, но не видел, чтобы кто-то использовал «встроенное пространство имен» для управления конкретным кодом платформы.встроенный метод пространства имен для управления конкретным кодом платформы в C++

Листы github repo дают конкретный код и пример использования. https://github.com/dchichkov/curious-namespace-trick/wiki/Curious-Namespace-Trick

Мне интересно, если это жизнеспособная техника для использования или есть какие-либо ошибки, которые я не могу видеть. Ниже приведен фрагмент кода:

#include <stdio.h> 

namespace project { 
    // arm/math.h 
    namespace arm { 
    inline void add_() {printf("arm add\n");} // try comment out 
    } 

    // math.h 
    inline void add_() { 
    // 
    printf("common add\n"); 
    // 
    } inline namespace platform {inline void add() {add_();}} 


    inline void dot_() { 
    // 
    add(); 
    // 
    } inline namespace platform {inline void dot() {dot_();}} 
} 

int main() { 
project::dot(); 
return 1; 
} 

Выход:

$ г ++ func.cpp -Dplatform = общий; ./a.out общий добавить

$ g ++ func.cpp -Dplatform = arm; ./a.out arm add

+2

Хотя полезно ссылаться на источник, вы также должны скопировать и вставить минимальный фрагмент кода здесь (и правильно отформатировать его!), Который демонстрирует то, что вы описываете. –

+0

Он не используется, потому что inline namespaces является новой функцией и не поддерживается широко, но этот сценарий является одной из основных причин их существования. Это не очень любопытно или трюк. –

+0

@JonathonReinhart Обновлен с помощью фрагмента кода. – Tej

ответ

0

Существует не менее двух способов достижения таких же результатов. Первый с пространствами имен. Второй - со статическими функциями в классах.

С пространствами имен:

#include <stdio.h> 

namespace GenericMath 
{ 
    void add(); 
    void dot(); 
} 

namespace ArmMath 
{ 
    void add(); 

    using GenericMath::dot; 
} 

namespace GenericMath 
{ 
    void add() 
    { 
     printf("generic add"); 
    } 

    void dot() 
    { 
     Math::add(); 
     printf("generic dot"); 
    } 
} 

namespace ArmMath 
{ 
    void add() 
    { 
     printf("arm add"); 
    } 

    using GenericMath::dot; 
} 

int main() 
{ 
    Math::dot(); 
    return 1; 
} 

С классами:

#include <stdio.h> 

class GenericMath 
{ 
public: 
    static void add(); 
    static void dot(); 
}; 

class ArmMath : public GenericMath 
{ 
public: 
    static void add(); 
}; 

void GenericMath::add() 
{ 
    printf("generic add"); 
} 

void GenericMath::dot() 
{ 
    printf("generic dot"); 
    Math::add(); 
} 

void ArmMath::add() 
{ 
    printf("arm add"); 
} 

int main() 
{ 
    Math::add(); 
    Math::dot(); 
    return 1; 
} 

IMO рядный имен s сделать код менее читаемым и слишком многословным.

0

Однажды проблема заключается в том, что в отличие от #ifdef, компилятор все еще компилирует весь код, который не относится к текущей платформе.

Таким образом, вы не можете использовать его для работы с API-интерфейсами платформы.

+0

Ну, вы не можете полностью избежать предварительного процессора. Но только с предварительным процессором он будет довольно волосатым. Даже под вопросом '# define' используется для выбора правильного пространства имен. –

+0

Правда, но в данном примере предварительный процессор выбирает вариант с включенным вариантом, но только принимает другие из набора поиска по умолчанию, а не полностью скрывает их от компилятора. Это, вероятно, хорошо во многих случаях (например, избегает bitrot на незащищенных путях), но это представляет собой ограничение. Вопрос был конкретно в строках имен в сравнении с '# ifdef'. – TBBle

+0

Я не вижу, где вопрос подразумевает отказ от использования '# ifdef' полностью. Я понял это как ** предварительный процессор только ** против ** предварительного процессора + встроенное пространство имен **. Может быть, автор может это прояснить? –