2016-01-07 2 views
0

В моем коде я использую несколько структур следующей структуры:Используйте переменную, чтобы определить, член структуры

struct Track { 
    string artist;      
    string cd;       
    // etc.... 
}; 

В Структуры могут быть отнесены к: Track1, Track2 и т.д.
Я нахожусь пытаясь сделать функцию, которая использует переменную, чтобы определить, какой элемент она должна выводить.
Например:

string x ="cd"         
cout << Track1.x << endl; 

Я не могу понять, как это сделать ... Я получаю ошибку, что «х» не является членом структуры.

Спасибо, что нашли время, чтобы прочитать это, я надеюсь, вы можете мне помочь.

+0

Какая у вас внешняя проблема? Зачем вам нужна такая функция? Как это будет называться? Что не так с кодом, как 'if (x ==" cd ") return o.cd;'? –

ответ

7

C++ не является языком сценариев, поэтому вы не можете выполнять такие переменные переменные.

Обычный способ сделать это, чтобы использовать карту вместо:

std::map<std::string, std::string> myValues; 

Тогда следующие такие же:

std::cout << myValues["cd"] << std::endl; 

и

std::string x = "cd"; 
std::cout << myValues[x] << std::endl; 

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

Но я предлагаю пересмотреть необходимость «переменных переменных» здесь, в первую очередь. Передача строки в функцию для определения ее семантики не кажется особенно эффективной, надежной или устойчивой. Почему бы не вернуть ссылку на весь объект Track, тогда вызывающий может проверить любое свойство, которое они хотят?

std::cout << getTrack(arguments...).cd << std::endl; 
+0

спасибо за быстрый ответ! Я новичок в C++, поэтому я очень ценю ваши объяснения. Прошу прощения, если не ясно, зачем я использую этот метод. Я удалил некоторые неочевидные понятия, чтобы сделать проблему более читаемой. Потребуется некоторое время, чтобы понять/реализовать твинов и объяснить проблему немного лучше (у меня есть некоторые трудности с этим на английском). –

+0

@JonasWest: ok. –

0

Это не представляется возможным указать учащемуся на время выполнения имени а. Единственная непосредственная функция языка, которая позволяет указать член класса по времени выполнения (т. Е. По мере того, как вы ставите его «использовать переменную для определения элемента структуры»), это указатели типа «указатель на элемент»

Track track1 = { "Some Artist", "Some CD" }; 
Track track2 = { "Some Other Artist", "Some Other CD" }; 

std::string Track::*member = &Track::cd; // pointer-to-member points to 'cd' member 
std::cout << track1.*member << std::endl; 
std::cout << track2.*member << std::endl; 

member = &Track::artist; // pointer-to-member points to 'artist' member 
std::cout << track1.*member << std::endl; 
std::cout << track2.*member << std::endl; 

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

std::map<std::string, std::string Track::*> mapping = { 
    { "artist", &Track::artist }, 
    { "cd", &Track::cd } 
}; 

std::string Track::*member = mapping["cd"]; 
std::cout << track1.*member << std::endl; 
std::cout << track2.*member << std::endl; 
+0

спасибо за быстрый ответ! Я новичок в C++, поэтому я очень ценю ваши объяснения. Прошу прощения, если не ясно, зачем я использую этот метод. Я удалил некоторые неочевидные понятия, чтобы сделать проблему более читаемой. Потребуется некоторое время, чтобы понять/реализовать твинов и объяснить проблему немного лучше (у меня есть некоторые трудности с этим на английском). –

Смежные вопросы