2014-11-19 14 views
5

Ben gibi kod biraz varsa:std :: niteleyici ad alanı işlevi mevcut olduğunda gerekli mi?

using namespace std; 

namespace myNamespace 
{ 
    vector<float> sqrt(vector<float> v) { return v; } 

    void func() 
    { 
     vector<float> myVec = { 1, 2, 3, 4 }; 
     std::cout << sqrt(myVec)[0] << std::endl; 
     float myFloat = 4.0f; 
     std::cout << sqrt(myFloat) << std::endl; // need to use std::sqrt() 
    } 
} 

Ben std::sqrt kullanmak işaretli çizgi değişti sürece o zaman derlemek olmaz. Niye ya? myNamespace numaralı telefondan sqrt(float)'u yeniden tanımlamayı denediysem, standart kitaplık sürümünü kullanmak istediğimde std:: ile kalifiye olmam gerektiğini anlıyorum. Derleyici, başka bir (std) ad alanındaki bir işlevi kullanmak yerine myFloat'u dönüştürmeyi deniyor gibi görünüyor. Bunu aşmanın bulundu

bir yolu std ad alanında sqrt(vector<float>) tanımlamaktır ama bu pek doğru gelmiyor ve this question cevapları std yılında aşırı yasadışı gösteriyor. Muhtemelen o zaman gitme yolu yok ...

sqrt (veya başka herhangi bir standart kitaplık cmath işlevi, bu konu için) aşırı yükleyebilirim, böylece derleyicinin hangisini kullanacağına ve derleyiciye sahip olmam gerekmeyecek Geçilen işlev parametrelerini temel alarak seçin?

Teşekkürler.

+1

olduğunu. Küresel isim alanında onu * ilan edebilirdiniz, çünkü bir sebepten dolayı std'yi terk ettiniz. Veya 'sqrt'unuzun yanında, ad alanınıza std :: sqrt;' kullanarak ekleyebilirsiniz. İsmi doğru olarak nitelendiririm. –

+1

Ayrıca, 'namespace somomingsomething' kullanarak da kullanamazsınız ve her zaman std :: prefix'i kullanabilirsin, bu şekilde tamamen saçmalıktan kaçının. – Cubic

cevap

9

uygun sqrt bulacaktır, name lookup parametreleri türü umursamayan sadece adı. Derleyici, sqrt adlı bir işlevi aradığında, her zaman ilk önce sürümünüzü bulur (arama, görünen ad alanı ile başladığından beri) ve orada durur.

Sen ad alanında bir using yönergesi ile kapsam içine std:: adını getirerek derleyici yardımcı olmalıdır

: Sonra

namespace myNamespace 
{ 
    using std::sqrt 
    ... 
} 

, standart aşırı yük çözünürlük ayırt gerçekleşecek sizin sqrt ve std::sqrt ve irade çağrılacak doğru sqrt işlevini seçin. Argument Dependent Lookup (ADL) adı için std::sqrt kullanılabilir hale getirir,

  • olarak basit işaret ettiği:

    hep adını (std::sqrt veya myNamespace::sqrt)


    Notlar hak etmelidir, herhangi belirsizlik olmaması için ilk durumda arama (vectorstd:: içinde olduğundan), ancak karşılaştığınız sorunu değiştirmez.

  • std:: kendi sqrt fonksiyonunu bildirilmesi `std` ad alanında kendi işlevini bildirilmesi kesinlikle yanlıştır (şablon uzmanlık hariç standardına göre yasak) çok kötü bir fikir

+0

Tüm std :: adlarını geçerli ad alanına getirmenin bir yolu var mı? Std :: * kullanımı gibi bir şey? – user2746401

+2

Ancak, parametre türlerini önemsiyor. 'Sqrt'un ilk çağrısında, derleyici ADL aracılığıyla 'myNamespace :: sqrt' ve' std :: sqrt' öğelerini bulmuş olacaktır (çünkü 'vector' std' içinde). Sadece 'myNamespace :: sqrt' seçer çünkü daha iyi bir eşleşme. – Simple

+0

@Simple: iyi nokta, not eklendi – quantdev

2

Sen myNamespace içinde deyimi using std::sqrt; yoluyla ad içine std::sqrt getirebilir:

namespace myNamespace 
{ 
    vector<float> sqrt(vector<float> v) { return v; } 
    using std::sqrt; 
    ... 

Sonra derleyici std::cout << sqrt(myFloat) C++