2011-01-03 2 views
6

Следующий фрагмент кода работает для меня:шаблоны член-функций и перегрузкой оператора() в C++

class Foo { 
public: 
    template <class T> T& get() { ... } 
}; 

Foo foo; 
foo.get<int>() = ...; 

Однако, следующий фрагмент кода не работает для меня:

class Foo { 
public: 
    template <class T> T& operator()() { ... } 
}; 

Foo foo; 
foo<int>() = ...; 

Ошибки являются:

expected primary-expression before '>' token 
expected primary expression before ')' token 

Обе ошибки относятся к foo<int>()

Почему это не работает, и можно ли это исправить?

+1

Ваш шаблон 'operator()' довольно непригоден, поскольку его экземпляры будут перегружать только возвращаемое значение. Продолжайте использовать имя 'get' или подобное. – aschepler

+0

Это не непригодно (хотя это может быть не предпочтительнее). См. Ответы ниже. –

+0

Почему вы плакалите функции, но не класс в целом? –

ответ

10

Если вам нужно явно указать аргумент шаблона, вам нужно будет использовать operator синтаксис:

foo.operator()<int>() 

Существует нет способа указать аргументы, используя синтаксис вызова функции. Если вы не можете вывести аргументы шаблона из аргументов функции, лучше использовать функцию-член, чем перегрузку оператора.

+0

Ах, действительно, спасибо. Теперь это имеет смысл. – Dan

-1

В качестве альтернативы вы можете сделать это

class Foo { 
public: 
    template <class T> operator T&() { ... } 
}; 

Тогда он будет автоматически вызывать правильную функцию в зависимости от типа «возврата»:

Foo foo; 
int i=foo; 

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

+3

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

+2

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

1

Проблема в том, что список параметров шаблона находится не в том месте; это как если бы вы пытались использовать объект или функцию с именем foo с аргументом шаблона int, но на самом деле это operator(), что вы хотите включить список параметров шаблона.

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

class Foo { 
public: 
    template <class T> T& operator()() { ... } 
}; 

Foo foo; 
foo.operator()<int> = ...; 

Надеюсь, это поможет.

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