2009-08-14 3 views
1

Если я хочу создать шаблон функции, где параметр шаблона не используется в списке аргументов, я могу это сделать таким образом:шаблоны оператора в C++

template<T> 
T myFunction() 
{ 
//return some T 
} 

Но вызов должен указать «T 'использовать, поскольку компилятор не знает, как это работает.

myFunction<int>(); 

Но, предположим, я хотел сделать что-то подобное, но для оператора []. шаблон

T SomeObject::operator [ unsigned int ] 
{ 
    //Return some T 
} 

Есть ли способ вызова этого оператора? Это не появляется в силе:

SomeObject a; 
a<int>[3]; 

ответ

6

Это должно работать:

class C 
{ 
public: 
    template <class T> 
    T operator[](int n) 
    { 
     return T(); 
    } 
}; 

void foo() 
{ 
    C c; 

    int x = c.operator[]<int>(0); 
} 

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

+0

Ницца, я не знал, что вы можете это сделать! Но да, это так побеждает превосходство использования перегрузки оператора вообще. – Scott

+1

Действительно. Обычно он переименовывается в 'get()'. – GManNickG

+0

Разве оператор [] не должен возвращать ссылку? – navigator

2

Вы можете использовать a.operator [] <INT> (1); Но зачем вам это нужно?

1

Это не может быть оптимальным решением, но вы можете напрямую позвонить оператору, как например:

a.operator[](3);

Я попробовал это в г ++ со следующим испытанием:

class MyClass { 
public: 
    template<class T> 
    T operator[](unsigned int) { 
     // do something 
     return T(); 
    } 
}; 

int main(int argc, char* argv[]) { 
    MyClass test; 
    test.operator[]<int>(0); 
    //test<int>[0]; // doesn't compile, as you mentioned 
    return 0; 
}
+0

Было действительно замечательно, как быстро это получило ответ. Когда я печатал это, я продолжал видеть ответы, которые вы отправляли, и все они практически идентичны. Думаю, я просто не был достаточно быстрым :) – John

1

Если вам нужно define operator [], то, вероятно, определите шаблон на уровне класса. Что-то вроде этого:

template<class T> 
class C 
{ 
public: 
    T operator[](int n) 
    { 
     return T(); 
    } 
}; 

int main() 
{ 
    C<int> c; 

    int x = c[0]; 

    return 0; 
} 
+0

Мне это нужно было в одном классе, который обрабатывает кучу разных типов через один экземпляр, а не кучу специализированных классов, которые обрабатывают свои собственные экземпляры. Я думаю, что мне просто нужно пойти на форму Object.func ()! – Scott

0

У меня есть трудное время придумать пример, где это было бы необходимо (не мог просто перегрузки оператор вместо этого?), Но вот мои мысли так или иначе:

Поскольку вы не можете использовать синтаксис оператора infix с templatized операторами, вы можете захотеть создать экземпляр шаблона до, который вы вызываете оператором. Прокси-сервер может быть способом сделать это.

class some_class { 
private: 
    template<class T> class proxy { 
    some_class* that_; 
    public: 
    proxy(some_class* that) : that_(that) {} 
    T& operator[](std::size_type idx) {return that->get<T>(idx);} 
    }; 

    template<class T> class const_proxy { 
    some_class* that_; 
    public: 
    proxy(const some_class* that) : that_(that) {} 
    const T& operator[](std::size_type idx) const {return that->get<T>(idx);} 
    }; 

    template< typename T >  proxy<T> get_array()  {return proxy<T>(this);} 
    template< typename T > const_proxy<T> get_array() const {return proxy<T>(this);} 

    template< typename T >  T& get(std::size_t idx)  {/* whatever */} 
    template< typename T > const T& get(std::size_t idx) const {/* whatever */} 
}; 

// This is a lousy use case. 
// Did I already say I have a hard time imagining how to use this? 
template< typename T > 
void f(some_class& some_object, sid::size_t idx) 
{ 
    T& = some_object.get_array<T>()[idx]; 
} 
4

Boost.Program_options использует этот аккуратный синтаксис:

int& i = a["option"].as<int>(); 

что достигается с чем-то вроде этого:

class variable_value 
{ 
public: 
    variable_value(const boost::any& value) : m_value(value) {} 

    template<class T> 
    const T& as() const { 
     return boost::any_cast<const T&>(m_value); 
    } 

    template<class T> 
    T& as() { 
     return boost::any_cast<T&>(m_value); 
    } 

private: 
    boost::any m_value; 
}; 

class variables_map 
{ 
public: 
    const variable_value& operator[](const std::string& name) const 
    { 
     return m_variables[name]; 
    } 

    variable_value& operator[](const std::string& name) 
    { 
     return m_variables[name]; 
    } 

private: 
    std::map<std::string, variable_value> m_variables; 
}; 

Вы могли бы приспособить эту идею, чтобы удовлетворить свои собственные потребности.

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