2015-02-11 3 views
0

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

3.4.3.2.2: Для имен X и имя мов, пространство имен квалифицированного поиска множества S (X, т) определяется следующим образом: Пусть S '(X, m) является множеством всех объявлений m в X и встроенного пространства имён X (7.3.1). Если S '(X, m) не пусто, S (X, m) есть S' (X, m); в противном случае S (X, m) представляет собой объединение S (N_i, m) для всех пространств имен N_i, номинированных с помощью директив в X и его встроенного пространства имен.

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

#include <type_traits> 
namespace foo 
{ 
    template<class Ty> 
    struct remove_extent 
     { 
     typedef Ty type; 
     }; 
} 
namespace fallback 
{ 
    using namespace std; 
} 
namespace fallback 
{ 
    using namespace foo; 
} 
template<typename Ty> 
struct Bar 
{ 
    typename fallback::remove_extent<Ty>::type var; 
}; 
int main() 
{ 
    Bar<int[]> var; 
} 

Для первой декларации

namespace fallback 
{ 
    using namespace std; 
} 

S'(fallback, remove_extent) является пустое множество, так S(fallback, remove_extent) является объединение S(std, remove_extent).

Для второй декларации

namespace fallback 
{ 
    using namespace foo; 
} 

S'(fallback, remove_extent) непусто так S(fallback, remove_extent) = S'(fallback, remove_extent) = S(std, remove_extent)

, но мой компилятор думает иначе и жалуется

1>source.cpp(21): error C2872: 'remove_extent' : ambiguous symbol 
1>   could be 'source.cpp(6) : foo::remove_extent' 
1>   or  'c:\program files (x86)\microsoft visual studio 11.0\vc\include\type_traits(331) : std::remove_extent' 

Так, очевидно, мое понимание является неправильным. Почему компилятор включает в себя имя remove_extent от foo?

ответ

4

Для второй декларации ... S'(fallback, remove_extent) непусто

Нет, это не так:

namespace fallback 
{ 
    using namespace std; 
} 

После этой точки S'(fallback, remove_extent) пусто, так S является S(std, remove_extent) ,

namespace fallback 
{ 
    using namespace foo; 
} 

После этой точки S'(fallback, remove_extent) является еще пустой (т.е. там до сих пор нет декларации о remove_extentнепосредственно вfallback), так S теперь объединение S(std, remove_extent) и S(foo, remove_extent).

template<typename Ty> 
struct Bar 
{ 
    typename fallback::remove_extent<Ty>::type var; 
}; 

Когда мы дойдем до этой точки, есть две сущности, названные remove_extent в fallback (один из std и один из foo, ни объявленных непосредственно в fallback), так что компилятор правильно говорит, что имя неоднозначно.

Смежные вопросы