Разрешение перегрузки функции с nullptr в качестве аргумента - PullRequest
0 голосов
/ 22 февраля 2019

Рассмотрим код ниже.Хотя обе перегрузки fun принимают указатели, передача nullptr в fun не приводит к ошибке компиляции.Принимая во внимание, что очень похожая функция bun не компилируется.Когда я печатаю типы аргумента i, используя typeid(i).name() (после изменения кода просто для печати) я получаю тот же тип, просто int*.Какое правило разрешает неоднозначность в случае fun, но не выполняется для bun?Заранее спасибо!

#include <iostream>

struct Foo {
    int sth;
};

template< class U>
void fun(decltype(U::sth)* i){
    std::cout << "1" << std::endl;
}

template< class U>
void fun(U* i){
    std::cout << "2" << std::endl;
}

void bun(decltype(Foo::sth)* i){
    std::cout << "3" << std::endl;
}

void bun(Foo* i){
    std::cout << "4" << std::endl;
}

int main ( )
{
    fun<Foo>(nullptr);
    // bun(nullptr); --> call of overloaded 'bun(std::nullptr_t)' is ambiguous        
    return 0;          
}
-----------------------
output : 1

1 Ответ

0 голосов
/ 22 февраля 2019

Ну, на самом деле, GCC принимает ваш код, но Clang не .Поэтому на первый взгляд неясно, является ли вызов неоднозначным.

Вы спрашиваете, какое правило разрешает неоднозначность в случае fun;GCC, очевидно, считает, что такое правило существует.Я полагаю, что правило, которое применяет GCC, это правило [over.match.best] /1.7, которое предпочитает более специализированный шаблон функции по сравнению с менее специализированным.

Процедура определения того, какойШаблон функции более специализирован, чем другой, описанный в [temp.func.order] и подробно объясненный в этом ответе SO .Однако вы заметите, что при попытке применить эту процедуру к двум перегрузкам fun, как в этом вопросе, мы сталкиваемся с проблемой, что уникальный синтезированный тип, который должен быть заменен на U в первой перегрузке, будет нуждатьсяиметь элемент с именем sth, и природа этого члена не указана, и хотя человеку может быть ясно, что удержание при второй перегрузке fun должно завершиться успешно независимо от типа sth,возможно, компилятор не сможет это доказать.

Это CWG 1157 .Поскольку этот вопрос все еще остается открытым без предлагаемого решения, у меня нет понимания, намеревается ли WG21 добиться успеха в решении по этой перегрузке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...