Intel C++ derleyicisini kullanıyoruz ve boost::function<Ponies()> f(unnamedNamespacedFunctor)
kullanımından indirgenerek aşağıdakileri (?) Yanlış şekilde derlediğini tespit ettik.T = <adsız ad-sınıfı sınıf> ile işlev şablon uzmanlarının statik yerlileri benzersiz olmak için gerekli midir?
a1.cc:
template<typename T>
int f(T) { static int x = T::x; return x; }
namespace { struct A { static const int x = 1; }; }
int f1() {
return f(A());
}
a2.cc:
template<typename T>
int f(T) { static int x = T::x; return x; }
namespace { struct A { static const int x = 0; }; }
int f2() {
return f(A());
}
main.cc:
#include <cstdio>
int f1();
int f2();
int main() {
std::printf("%d != %d\n", f1(), f2());
}
Komut satırı:
# icpc a1.cc a2.cc main.cc -o main
# ./main
0 != 0
Sorum şu: Bu uyumlu mu? Bu tür örneklemelerde durağan yerliler kullanıldığında tanımlanmamış davranışlar ortaya çıkıyor mu? üretilen semboller teftiş, ben tahmin ettiğim gibi x
statik değişken zayıf bağlantıyı alır ve bu nedenle iki x
'es birleştirilir ve seçilir piyango olur f
iken yerel bağının olduğunu belirtti
# icpc a2.cc a1.cc main.cc -o main
# ./main
1 != 1
Yardım için minnettar olurum. Belki de bu aslında bir derleyici-hatadır ve daha önce bildirilmiştir?
, bu aynı zamanda, struct A'lardan birini yeniden adlandırırsanız, bu da oluşur. Yapı B? –
ODR'nin ihlali anlamında f değil midir? ODR ihlali gidermek için kendi yerel ad alanlarındaki iki f tanımı kullanılırsa ne olur? – MSalters
@MSalters, aynı şeyi kolayca değiştiremediğim boost :: function ile gerçekleşir :) Eğer bir ODR ihlali ise, mevcut uygulamaya karşı olduğunu sanırım. Bunu yasaklayan bir kural bulamadım. İşlev şablonu örneğinin bağlantısı haricidir, ancak argüman türü iç bağlantıya sahiptir (ve dolayısıyla farklı TU'larda farklı bir tiptir!). Bunu yasaklayan bir paragraf bulamıyorum ve bunu yasaklamak için bir neden olduğundan emin değilim. –