İlk bazı kod, bazı bağlam ve ardından soru:Değişkin şablon adlar sonra
template <typename T> using id = T;
template <template <typename...> class F, typename... T>
using apply1 = F <T...>;
template <template <typename...> class F>
struct apply2
{
template <typename... T>
using map = F <T...>;
};
// ...
cout << apply1 <id, int>() << endl;
cout << apply2 <id>::map <int>() << endl;
clang 3.3 ve gcc 4.8.1 Hem böylece hem int
kimlik üst-işlevin uygulayarak hatasız bu derleme ifadeleri varsayılan int
(sıfır) olarak değerlendirir.
id
bir template <typename>
apply1
ederken, apply2
bir template <typename...>
ilk etapta endişe bana yaptığı beklemek olması. Ancak, bu örneğin işe yarayacağı oldukça elverişlidir, çünkü apply1
, apply2
gibi metafonksiyonlar çok daha fazla dahil edilmelidir.
Diğer yandan, bu tür takma adlar gerçek dünyadaki kodda ciddi şekilde sorun yaratamazlar: burada gcc için sık karşılaşılan derleyici hataları ve daha az sık karşılaşılan beklenmedik davranışlar (yalnızca daha gelişmiş SFINAE testlerinde).
deneme yanılma ay sonra, şimdi yükleyin ve (deneysel) gcc 4.9.0 kod deneyin ve burada hata geliyor:
test.cpp: In instantiation of ‘struct apply2<id>’:
test.cpp:17:22: error: pack expansion argument for non-pack parameter ‘T’ of alias template ‘template<class T> using id = T’
using map = F <T...>;
^
Tamam, yüzden bu kod değilmiş tüm bu zaman geçerli, ancak gcc hata raporlama yerine çeşitli şekillerde çöktü. İlginç bir şekilde, apply1
, apply2
eşdeğer gibi görünürken, hata yalnızca apply2
için bildirilmiştir (bu uygulamada çok daha yararlıdır). Clang gelince, gerçekten söyleyemem. Pratikte, gcc 4.9.0 ile devam etmek ve kodu daha karmaşık hale getirse de düzeltmek için başka bir yolum yok gibi görünüyor.
Teoride, standardın ne dediğini bilmek isterim: bu kod geçerli midir? Değilse, apply1
kullanımı da geçersiz midir? veya sadece apply2
?
DÜZENLEME
Hemen yaşadım bütün sorunlar bugüne kadar şablon diğer adları değil, şablon yapılar başvurmak açıklığa kavuşturmak için.
template <typename T> struct id1 { using type = T; };
// ...
cout << typename apply1 <id1, int>::type() << endl;
cout << typename apply2 <id1>::map <int>::type() << endl;
Bu clang 3.3, gcc 4.8.1, GCC 4.9.0 üzerine, her iki durumda da 0
ince derler ve baskılar: Örneğin, aşağıdaki modifikasyon düşünün. Çoğu durumda, geçici çözümlerim, diğer addan önce bir ara şablon yapısını tanıtıyor. Üste | Ancak, şimdi, jenerik SFINAE testlerini parametrize etmek için metafonksiyonları kullanmaya çalışıyorum ve bu durumda, doğrudan takma adları kullanmam gerekiyor, çünkü yapıların somutlaştırılmaması gerekiyor. Sadece bir fikir edinmek için, gerçek kodun bir parçası here'dur.
Deneysel GCC 4.9'un hata mesajı bana mantıklı gelmiyor ve FWIW kodun geçerli olduğunu düşünüyorum. –
İlgili? http://stackoverflow.com/q/18724698/420683 – dyp
Teşekkürler, bu soru 'foo', foo2', foo_variadic' gibi özel durumlarla ilgili şablonların tam olarak düzeltmeyi planladığım yollarla ilgilidir. eğer zorundaysam. Ancak, yukarıda düzenlediğim gibi, sorunlarım yalnızca şablon takma adlarıyla görünüyor. – iavr