2013-08-30 6 views
1

Можно ли иметь оператор, не являющийся членом как, не являющиеся членов в качестве частного члена иностранного класса

bool operator==(const std::string &l, const Token r) 

в качестве частной функции члена неродственного класса Interpreter? Я пробовал это очевидным образом, но он не работает (слишком много аргументов). я знаю, уже название «функции, не являющиеся членами [...] в качестве члена» говорит обратное, но есть лучший способ, чем функция

bool isToken(const std::string &l, const Token r) 

сделать сравнение, которое зависит от а (нестатический) член Interpreter?

Невозможно сравнить Token s с string за пределами Interpreter.

Дополнительная информация: токен - это перечисление, и сравнение зависит от языка, установленного для построения Interpreter.

+1

Что такое 'токен', и как будет работать' '' '', если 'токен' был LHS? – jxh

+0

Токен - это перечисление типа KEYWORD_ELSE или CONDITION_ALWAYS. KEYWORD_ELSE == «else» должен быть правдивым для «английского» интерпретатора и KEYWORD_ELSE == «sonst» должен быть правдой для «немецкого» переводчика. – Fabian

+0

Также, как вы представляли себе синтаксис, как если бы оператор == был определен внутри Intepreter?Или вы просите оператора, который будет работать только в контексте интерпретатора, т. Е. Для методов членов интерпретатора? –

ответ

1

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

Если вы хотите «дублировать код», вы можете играть в трюки с пространствами имен. Ваш общий интерпретатор может быть шаблоном, который принимает определенный для языка производный класс в качестве параметра шаблона. Он, в свою очередь, вызывает шаблоны operator== на основе специфического для языка токена.

template <typename TOKEN> 
bool operator == (const std::string &l, const TOKEN token) { 
    return token == l; 
} 

// Language specific interpreters inherit from this template 
template <typename LANG> 
class Interpreter { 
public: 
    void interpret() { 
     std::string s("hi"); 
     if (s == LANG::KEYWORD_ELSE) {} 
    } 
}; 

Каждый язык конкретный подкласс Interpreter лежит в конкретном языке имен. Реализация повторяет перечисления ключевых слов, но в противном случае отменяет реализацию шаблона.

namespace Lang0 { 
    class Interpreter : public ::Interpreter<Lang0::Interpreter> { 
     //... 
    public: 
     enum Token { KEYWORD_ELSE, //... 
        }; 
     static Interpreter & instance() { 
      static Interpreter interpreter; 
      return interpreter; 
     } 
    }; 
} 

namespace Lang1 { 
    class Interpreter : public ::Interpreter<Lang1::Interpreter> { 
     //... 
    public: 
     enum Token { KEYWORD_ELSE, //... 
        }; 
     static Interpreter & instance() { 
      static Interpreter interpreter; 
      return interpreter; 
     } 
    }; 
} 

Каждое пространство имен также обеспечивает язык для конкретной реализации operator== сравнивать строки на конкретном языке лексемы.

namespace Lang0 { 
    bool operator == (const Interpreter::Token token, const std::string &l) { 
     //... 
    } 
} 

namespace Lang1 { 
    bool operator == (const Interpreter::Token token, const std::string &l) { 
     //... 
    } 
} 

Затем, когда реализация шаблон Interpreter называет версию шаблона operator==, он решает на языке конкретной реализации на соответствующем языке конкретного пространства имен.

+0

Неправильное копирование кода, к сожалению. Интерпретатор загружает заданную базу данных с переводом на карту. Есть ли причина, по которой C++ не допускает этого или не был забыт/не был предназначен? – Fabian

+0

Я не уверен, как ответить на ваш вопрос. Я был под впечатлением, так как вы хотели поместить 'operator ==' в качестве члена 'Interpreter', чтобы сравнения выполнялись только в контексте экземпляра' Interpreter'. Вот почему я думал, что вышеупомянутое решение сработает для вас. Я предположил, что английский переводчик будет другим примером, чем Deutsch Intepreter. – jxh

+0

[Здесь] (http://ideone.com/Obq7Sl) - это макет по IDEONE того, что я имел в виду. – jxh

0

Поскольку сравнение производится нестационарным членом интерпретатора (скажем, is_equal()), вам нужно три объекта для сравнения: интерпретатор, строка и токен.

Если вы знаете, что на момент сравнения имеется только один действительный экземпляр объекта Interpreter, вы могли бы сделать этот экземпляр доступным статически, например.

bool operator==(const std::string &l, const Token r) 
{ 
    return Interpreter::instance().is_equal(l, r); 
} 

где static member instance() возвращает объект Interpreter, который выполняет работу.

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