在嘗試實作一個元函式時,該元函式僅在某些型別存在“abs”函式時才需要存在,我遇到了以下問題:
這是我希望產生相同結果的兩個代碼示例,但實際上它們不會:
第一個例子
#include <iostream>
#include <cmath>
using namespace std;
struct Bar{};
template<typename T>
int abs(T& v)
{
return -1;
}
void test()
{
Bar b;
double x = -2;
cout << abs(x) << endl;
cout << abs(b) << endl;
}
int main()
{
test();
}
產量:
2
-1
這是我所期望的
第二個例子
#include <iostream>
#include <cmath>
namespace Foo
{
struct Bar{};
using namespace std;
template<typename T>
int abs(T& v)
{
return -1;
}
void test()
{
Bar b;
double x = -2;
cout << abs(x) << endl;
cout << abs(b) << endl;
}
}
int main()
{
Foo::test();
}
產量:
-1
-1
為什么在這里使用命名空間會使編譯器優先考慮“本地”abs 方法而不是 std::abs?
uj5u.com熱心網友回復:
在第二種情況下, using 指令將宣告的名稱放在全域名稱空間中的指定名稱空間中,以進行非限定名稱查找。因此,在命名空間中找到了在該命名空間中宣告Foo的非限定名稱abs。即abs命名空間中宣告的名稱Foo隱藏abs了全域命名空間中宣告的名稱。
來自 C 14 標準(7.3.4 Using 指令)
2 using-directive 指定指定命名空間中的名稱可以在 using-directive 出現在 using-directive 之后的范圍內使用。在非限定名稱查找 (3.4.1) 期間,名稱看起來好像它們是在最近的封閉命名空間中宣告的,其中包含使用指令和指定命名空間。[注:在此背景關系中,“包含”是指“直接或間接包含”。——尾注]
第二個程式中最近的封閉命名空間是全域命名空間。
下面還有兩個程式演示了使用 using 指令時非限定名稱查找的相同原理。
#include <iostream>
void s() { std::cout << "The function s() called.\n"; }
struct s
{
s() { std::cout << "The constructor of struct s called.\n"; }
};
void test()
{
s();
}
int main()
{
test();
}
程式輸出為
The function s() called.
在這個演示程式中,函式s的宣告隱藏了結構的宣告s。
第二個節目。
#include <iostream>
namespace N1
{
void s() { std::cout << "The function N1::s() called.\n"; }
}
namespace N2
{
using namespace N1;
struct s
{
s() { std::cout << "The constructor of struct N2::s called.\n"; }
};
void test()
{
s();
}
}
int main()
{
N2::test();
}
程式輸出為
The constructor of struct N2::s called.
在這種情況下,具有名稱的結構的宣告s隱藏了具有相同名稱的函式,該函式s的宣告由于 using 指令而被放置在全域命名空間中。
uj5u.com熱心網友回復:
對于發生這種情況的原因,您可以參考 Vlad 的回答。但是,如果您希望仍然能夠執行測驗,您可以在單獨的命名空間中進行測驗。
#include <iostream>
#include <cmath>
namespace Foo
{
template<typename T>
int abs(T& v)
{
return -1;
}
}
namespace Test
{
struct Bar{};
using namespace std;
using namespace Foo;
void test()
{
Bar b;
double x = -2;
cout << abs(x) << endl;
cout << abs(b) << endl;
}
}
int main()
{
Test::test();
}
輸出是
2
-1
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/410970.html
標籤:
上一篇:如何在C 類中初始化模板物件?
