Выберите заданное пространство имен во время выполнения

#c #namespaces

#c #пространства имен

Вопрос:

Допустим, у меня есть эти пространства имен:

 namespace old
{
std::array<std::string,1> characters {"old"};
}


namespace young 
{
std::array<std::string,1> characters {"young"};
}
  

Затем я хочу, чтобы пользователь вначале сообщил мне, какую версию он использует. Затем вызовите соответствующее пространство имен по всей программе.

Я пробовал using namespace в зависимости от входных данных, но это не работает, потому что мне нужно вызвать правильное пространство имен в функциях в других исходных файлах. Я подумал, может быть, я могу отправить пространство имен в качестве параметра функции? Или сделать что-нибудь умное с шаблонами?

РЕДАКТИРОВАТЬ: когда я говорю «пользователь», я имею в виду кого-то, кто использует мой исполняемый файл, человека, играющего в мою игру. Что я хочу сделать, так это спросить его, какую версию он собирается использовать, например, американскую версию (у вещей есть некоторые названия) или британскую версию (у вещей есть другие названия).

Все, что меняется, — это имена, которые я использую. Но я хочу, чтобы он мог каждый раз переключаться между версиями.

Я надеюсь, что это понятно, пожалуйста, дайте мне знать, если вам нужны дополнительные разъяснения.

Комментарии:

1. пространства имен оцениваются во время компиляции, поэтому вам придется решать это с помощью утилит, таких как макросы .

2. @StackDanny: Они работают во время компиляции, но, конечно, не для препроцессора

3. @Daniel: Предполагается, что пространство имен действительно меняется в зависимости от параметров времени выполнения или «пользователь» — это человек, который компилирует ваш код, и тот или иной должен быть определен только один раз во время компиляции?

4. @MikeMB Да, мне нужно изменить пространство имен в зависимости от пользовательского ввода. Я добавил некоторые подробности к вопросу.

5. Макросы @StackDanny расширяются еще до времени компиляции, так как же это должно помочь?

Ответ №1:

Невозможно передать пространство имен в качестве параметра функции или параметра шаблона. Пользователь может использовать его как:

 using namespace old;

characters[0] = 'O';
  

или код как:

 old::characters[0] = 'O';
  

ОБНОВЛЕНИЕ: после обновления исходного вопроса

Пространства имен актуальны во время компиляции и не отражают никакого поведения во время выполнения. Что вам нужно, так это больше похоже на:

 enum Language
{
    ENGLISH_UK, ENGLISH_US
};

std::array<std::string, 2> label = {
    "colour", // for British-english
    "color"   // for US-English
};
  

И затем в коде:

 static Language lang = ENGLISH_UK;

std::cout << label[lang] << std::endl;
  

Итак, если в пользовательском интерфейсе произошли изменения, вам не нужно перекомпилировать все приложение.

Комментарии:

1. Извините, если мой вопрос был неясен о том, что я назвал «пользователем». Я добавил больше информации к исходному вопросу

Ответ №2:

Короткий ответ — нет, потому что то, какие функции вызываются и к каким переменным обращаются в определенном месте вашего кода, когда вы, например, пишете characters , определяется во время компиляции.

Немного более длинный ответ заключается в том, что вы можете создавать функции-оболочки и ссылки в отдельном пространстве имен и пересылать их в одно или другое пространство имен в зависимости от пользователя (при условии, что типы одинаковы).

Например.

 namespace current {
    int namespace_to_use = 1; // can be set by some initialization function in your code

    std::array<std::string,1>amp; get_characters(){
       return namespace_to_use == 0 ? old::characters : young::characters; 
    }
}
  

Я бы не назвал это хорошим дизайном приложения, и есть много более продвинутых / улучшенных версий этого (например, основанных на динамическом полиморфизме и заводском шаблоне или указателях / ссылках). То, что подходит лучше всего, зависит от ваших потребностей и вашего уровня опыта.