Spec-Zone.ru › C++

Противоречивые объявления

Если не указано иное, два объявления не могут (снова) ввести ту же сущность. Программа является некорректной, если такие объявления существуют.

Соответствующие объявления

Два объявления соответствуют, если они (снова) вводят то же имя, оба объявляют конструкторы или оба объявляют деструкторы, за исключением случаев, когда

  • хотя бы одно является объявлением using declaration;
  • одно объявляет тип (не typedef name), а другое объявляет переменную, нестатическое данные члена, отличное от члена анонимного anonymous union, перечислитель, функцию или шаблон функции; или
  • каждое объявляет функцию или шаблон функции, и они не объявляют соответствующие перегрузки (см. ниже).


Два объявления функций объявляют соответствующие перегрузки, если оба объявляют функции, удовлетворяющие всем следующим условиям:

  • Они имеют тот же список типов параметров, опуская типы явных параметров объекта(с C++23).
  • У них есть эквивалентные заключительные ограничения (если есть, за исключением friend declarations).
(с C++20)
  • Если обе они являются нестатическими членами-функциями, они должны дополнительно удовлетворять одному из следующих требований:
  • Ровно одна из них является неявной функцией-членом объекта без квалификатора ссылки, и типы их параметров объекта, после удаления ссылок верхнего уровня, одинаковы.
(с C++23)
  • Их параметры объекта имеют одинаковый тип.


Два объявления шаблонов функций объявляют соответствующие перегрузки, если оба объявляют шаблоны функций, удовлетворяющие всем следующим условиям:

  • У них одинаковая длина списка параметров шаблона.
  • Их соответствующие параметры шаблона эквивалентны.
  • У них есть эквивалентные списки типов параметров, опуская типы явных параметров объекта(с C++23).
  • У них эквивалентные типы возвращаемых значений.
  • Их соответствующие параметры шаблона либо оба объявлены без ограничений, либо оба объявлены с эквивалентными ограничениями.
  • У них эквивалентные заключительные ограничения (если есть).
(с C++20)
  • Если оба являются нестатическими членами-шаблонами функций, они должны дополнительно удовлетворять одному из следующих требований:
  • Ровно один из них является шаблоном неявной функции-члена объекта без квалификатора ссылки, и типы их параметров объекта, после удаления всех ссылок, эквивалентны.
(с C++23)
  • Их параметры объекта имеют эквивалентные типы.
struct A
{
    friend void c();   // #1
};
 
struct B
{
    friend void c() {} // corresponds to, and defines, #1
};
 
typedef int Int;
 
enum E : int { a };
 
void f(int);   // #2
void f(Int) {} // defines #2
void f(E) {}   // OK, another overload
 
struct X
{
    static void f();
    void f() const;   // error: redeclaration
 
    void g();
    void g() const;   // OK
    void g() &;       // error: redeclaration
 
    void h(this X&, int);
    void h(int) &&;   // OK, another overload
 
    void j(this const X&);
    void j() const &; // error: redeclaration
 
    void k();
    void k(this X&);  // error: redeclaration
};

Возможные конфликты объявлений

Объявление является независимым от имени, если его имя _ и оно объявляет

  • переменную с автоматической продолжительностью хранения;
  • связку структур, которая не находится в области видимости пространства имен;
  • переменную, введенную с помощью захвата лямбда-выражения с инициализатором; или
  • нестатическое данные члена.
(с C++26)

Если не указано иное, два объявления сущностей объявляют одну и ту же сущность, если выполнены все следующие условия, учитывая объявления безымянных типов, вводящих их имена typedef и имена перечислений для целей связи (если таковые имеются):

  • Они соответствуют друг другу.
  • У них одинаковая целевая область видимости, которая не является областью видимости параметра функции или областью видимости параметра шаблона.
  • Ни одно из них не является объявлением, независимым от имени.
(с C++26)
  • Выполняется одно из следующих условий:
    • Они появляются в одном и том же исходном файле.
  • Оба объявляют имена с связью модуля и прикреплены к одному модулю.
(с C++20)
  • Оба объявляют имена с внешней связью.


Два объявления потенциально конфликтуют, если они соответствуют друг другу и приводят к тому, что их общее имя обозначает разные сущности. Программа является некорректной, если в любой области видимости имя связано с двумя объявлениями A и B, которые потенциально конфликтуют и A предшествует B, за исключением случаев, когда B является объявлением, независимым от имени.(с C++26)

void f()
{
    int x, y;
    void x(); // error: different entity for x
    int y;    // error: redefinition
}
 
enum { f };   // error: different entity for ::f
 
namespace A {}
namespace B = A;
namespace B = A; // OK, no effect
namespace B = B; // OK, no effect
namespace A = B; // OK, no effect
namespace B {} // error: different entity for B
 
void g()
{
    int _;
    _ = 0; // OK
    int _; // OK since C++26, name-independent declaration
    _ = 0; // error: two non-function declarations in the lookup set
}
 
void h ()
{
    int _;        // #1
    _ ++;         // OK
    static int _; // error: conflicts with #1 because
                  // static variables are not name-independent
}

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/language/conflicting_declarations

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API