Понимание стандартной грамматики С++ 03 для перегрузки оператора

Стандартная грамматика С++ 03 для перегрузки оператора выглядит следующим образом:

оператор-функция-идентификатор:
Оператор оператора
Оператор оператора Шаблон-аргумент-список? >

Первый - это обычный синтаксис перегрузки операторов, который мы обычно используем, например

Myclass operator + (Myclass s) {...}

Но что означает вторая альтернатива? В частности, в какой ситуации мы используем список шаблонов-аргументов? После быстрого просмотра С++ 11 я обнаружил, что вторая форма была удалена из стандарта. Каково было первоначальное намерение?

EDIT: после тестирования с VС++ 2010 ниже приведен один из способов использования вышеупомянутого синтаксиса, хотя для меня это не имеет особого смысла:

class K {
public:
    int a;
    template <int B>
    int operator + (int b) {
        return a+b+B;
    }
};


int _tmain(int argc, _TCHAR* argv[])
{
    K k;
    k.a=1;
    int s;
    s=k.operator+<115>(2);
    printf("%d\n",s);
    return 0;

}

output:118

Ответы

Ответ 1

Правило грамматики, которое позволяет специализировать шаблоны операторских функций, все еще существует в С++ 11, это просто в другом месте.

[temp.names]/1 (С++ 03):

Специализация шаблона (14.7) может ссылаться на шаблон-id:

шаблон-ID:

template-name < template-argument-listopt>

шаблон имя:

identifier

Шаблон-аргумент-список:

template-argument
template-argument-list , template-argument

шаблон аргументов:

assignment-expression
type-id
id-expression

[temp.names]/1 (С++ 11):

Специализация шаблона (14.7) может ссылаться на шаблон-id:

простой шаблон-ID:

template-name < template-argument-listopt>

шаблон-ID:

simple-template-id
operator-function-id < template-argument-listopt> <- HERE
literal-operator-id < template-argument-listopt>

шаблон имя:

identifer

Шаблон-аргумент-список:

template-argument ...opt
template-argument-list , template-argument ...opt

шаблон аргументов:

constant-expression
type-id
id-expression

Это, скорее всего, было сделано, потому что оператор-функция-id грамматического правила упоминается в контекстах, где этот список аргументов шаблонов не имеет смысла, поэтому они перевели правило куда-нибудь более разумным </endjecture> .


Вот пример этого правила в действии:

struct foo{
    template <typename T>
    void operator() (T t) { std::cout << t; }
};

template <>
void foo::operator()<double> (double) { 
    std::cout << "It a double!"; 
}

Обратите внимание на специализацию для operator(), если T - double. Если вы запустите этот код:

foo f;
f(0);
f(0.0);

Затем 0 будет напечатан для первого вызова, а It a double! для второго.

Живая демонстрация