Dikkat Mozza314
Burada, genel bir std::algorithm
aramanın etkilerinin bir simülasyonu std::swap
ve kullanıcının ad alanı std'deki takaslarını sağlaması. Bu bir deney olduğundan, bu simülasyon namespace exp
yerine kullanır namespace std
.
// simulate <algorithm>
#include <cstdio>
namespace exp
{
template <class T>
void
swap(T& x, T& y)
{
printf("generic exp::swap\n");
T tmp = x;
x = y;
y = tmp;
}
template <class T>
void algorithm(T* begin, T* end)
{
if (end-begin >= 2)
exp::swap(begin[0], begin[1]);
}
}
// simulate user code which includes <algorithm>
struct A
{
};
namespace exp
{
void swap(A&, A&)
{
printf("exp::swap(A, A)\n");
}
}
// exercise simulation
int main()
{
A a[2];
exp::algorithm(a, a+2);
}
Benim için bu çıktı:
generic exp::swap
Derleyiciniz farklı bir şey yazdırırsa, şablonlar için "iki aşamalı arama" işlemini doğru bir şekilde gerçekleştirmiyor demektir.
Derleyiciniz uyumluysa (C ++ 98/03 / 11'den herhangi birine), o zaman gösterdiğim çıktıyı verecektir. Ve bu durumda, olacağından tam olarak korktuğunuz şey olur. Ve swap
ad alanına std
( exp
) koymanız onun olmasını engellemedi.
Dave ve ben her ikimiz de komite üyeleriyiz ve on yıldır standardın bu alanında çalışıyoruz (ve her zaman birbirleriyle aynı fikirde değiliz). Ama bu mesele uzun zamandır çözüldü ve ikimiz de bunun nasıl çözüldüğü konusunda hemfikiriz. Dave'in bu alandaki uzman görüşünü / cevabını kendi sorumluluğunuzda göz ardı edin.
Bu sorun, C ++ 98 yayınlandıktan sonra gün yüzüne çıktı. 2001 yılından itibaren Dave ve ben bu alanda çalışmaya başladık . Ve bu modern çözüm:
// simulate <algorithm>
#include <cstdio>
namespace exp
{
template <class T>
void
swap(T& x, T& y)
{
printf("generic exp::swap\n");
T tmp = x;
x = y;
y = tmp;
}
template <class T>
void algorithm(T* begin, T* end)
{
if (end-begin >= 2)
swap(begin[0], begin[1]);
}
}
// simulate user code which includes <algorithm>
struct A
{
};
void swap(A&, A&)
{
printf("swap(A, A)\n");
}
// exercise simulation
int main()
{
A a[2];
exp::algorithm(a, a+2);
}
Çıktı:
swap(A, A)
Güncelleme
Şu şekilde bir gözlem yapılmıştır:
namespace exp
{
template <>
void swap(A&, A&)
{
printf("exp::swap(A, A)\n");
}
}
İşler! Öyleyse neden bunu kullanmıyorsun?
A
Bir sınıf şablonu olduğu durumu düşünün :
// simulate user code which includes <algorithm>
template <class T>
struct A
{
};
namespace exp
{
template <class T>
void swap(A<T>&, A<T>&)
{
printf("exp::swap(A, A)\n");
}
}
// exercise simulation
int main()
{
A<int> a[2];
exp::algorithm(a, a+2);
}
Şimdi tekrar çalışmıyor. :-(
Böylece swap
std ad alanına koyabilir ve çalışmasını sağlayabilirsiniz. Ama koymak hatırlamak gerekir swap
içinde A
bir şablon olduğunda durum için bireyin ad: A<T>
. Eğer koyarsanız hem vakalar çalışacaktır beri swap
de A
'ın ad, (ve öğretme başkalarına) sadece bunu tek yönlü olduğunu hatırlamak sadece daha kolaydır.