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

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

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

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

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

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

РЕДАКТИРОВАТЬ: после тестирования с помощью VC++ 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

person JavaMan    schedule 16.11.2016    source источник
comment
Что такое шаблонные операторы?   -  person JavaMan    schedule 16.11.2016
comment
Вы можете перегружать операторы для своего класса. И эти перегрузки могут быть шаблонными функциями.   -  person StoryTeller - Unslander Monica    schedule 16.11.2016
comment
@StoryTeller, но явные специализации не могут быть в области класса.   -  person Hatted Rooster    schedule 16.11.2016
comment
@GillBates Всегда есть специализации в виде бесплатных функций.   -  person StoryTeller - Unslander Monica    schedule 16.11.2016
comment
@StoryTeller Достаточно честно   -  person Hatted Rooster    schedule 16.11.2016


Ответы (1)


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

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

На специализацию шаблона (14.7) можно ссылаться по идентификатору шаблона:

идентификатор шаблона:

template-name < template-argument-listopt>

Имя Шаблона:

identifier

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

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

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

assignment-expression
type-id
id-expression

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

На специализацию шаблона (14.7) можно ссылаться по идентификатору шаблона:

идентификатор простого шаблона:

template-name < template-argument-listopt>

идентификатор шаблона:

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

Скорее всего, это было сделано из-за того, что грамматическое правило идентификатор-оператора-функции упоминается в контексте, где этот список аргументов шаблона не имеет смысла, поэтому они переместили правило в более разумное место ‹/гипотеза›.


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

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

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

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

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

Тогда для первого звонка будет напечатано 0, а для второго It's a double!.

Текущая демонстрация

person TartanLlama    schedule 16.11.2016
comment
Это имеет больше смысла, чем просто удалить его, если подумать :) - person StoryTeller - Unslander Monica; 16.11.2016
comment
См. основной вопрос 301. - person T.C.; 16.11.2016