簡體   English   中英

匿名命名空間中的變量聲明和其他地方的定義

[英]variables declaration in anonymous namespace and definition in other place

有人可以解釋為什么我不能將在匿名命名空間中聲明的變量定義為另一個地方的全局變量嗎?

#include <iostream>
namespace  {
    extern int number;
}

int number = 123;

void g() {
    std::cout << number;
}

編譯器說“對‘數字’的引用是模棱兩可的”,但我不明白為什么它將聲明和定義識別為不同的東西? 先感謝您。

對於非限定名稱查找,編譯器還考慮在全局命名空間中嵌套未命名的命名空間,

您在全局命名空間和嵌套的未命名命名空間中聲明了兩個具有相同名稱的不同對象。

未命名命名空間的 using 指令隱式插入到封閉的命名空間中。

考慮以下演示程序

#include <iostream>

namespace N
{
    extern int number;
}

using namespace N;

int number = 123;

int main()
{
    std::cout << number << '\n';
}

由於此語句中對名稱number的不合格引用的歧義,編譯器將發出錯誤

std::cout << number << '\n';

類似的情況發生在未命名的命名空間中,因為 using 指令隱式插入到封閉的命名空間中。

來自 C++ 20 標准(9.8.2 命名空間定義)

7 內聯命名空間的成員在大多數情況下都可以使用,就好像它們是封閉命名空間的成員一樣。 具體來說,內聯命名空間及其封閉命名空間都被添加到參數相關查找(6.5.3)中使用的關聯命名空間集合中,只要其中一個是,並且命名內聯命名空間的 using 指令(9.8.4)是對於未命名的命名空間(9.8.2.2),隱式插入到封閉的命名空間中

一般來說,聲明所聲明的名稱不會被查找——畢竟,當首次引入名稱時,您不能依賴於查找先前的聲明。 當然,還有一個類似的過程可以捕獲諸如

int x;
float x;

但是,由於它不是查找,它根本不受using的影響(包括未命名的命名空間)。 描述這種區別的另一種方式是聲明實體放入命名空間,因此無需考慮任何其他命名空間來決定將實體放置在何處。

在某些情況下,對declarator-id進行查找(可能是什么):

namespace N {using X=int;}
// using namespace N;
struct A {
  A(X());  // ?
};

A有一個沒有參數的成員函數,它返回一個名為XA (其聲明符周圍有無意義的括號); 但是,使用 using 指令,它反而有一個構造函數,該構造函數接受一個指向返回int的無參數函數的指針。 同樣,在聲明開頭

template<>
struct X<…

X 必須完全查找,即使顯式特化的聲明必須與模板位於相同的范圍內(內聯命名空間有余地),因為它可能會繼續

template<>
struct X<int>::Y<char> {…};

並且根本不是X的特化。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM