Техника встроенного пространства имен для управления специфичным для платформы кодом в C++

Я видел использование макросов #ifdef (пример библиотеки Eigen) для управления платформой, но не видел ни одного, использующего "встроенные пространства имен" для управления кодом, специфичным для платформы.

В репозитории github приведен конкретный код и пример использования. 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; 
} 

Выход:

$ g ++ func.cpp -Dplatform = common;./a.out обычное добавление

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

2 ответа

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

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

#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 делают код менее читабельным и слишком многословным.

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

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

Другие вопросы по тегам