Boost'un SFINAE yardımcılarının birçoğu, C++ 11 ile std kitaplığında görünmüştür, ancak has_dereference
görünmüyor. Bu özellikten başka, paketimin bir Boost bağımlılığını ortadan kaldırmayı başardım ve tamamen kurtulmak istiyorum, bu yüzden sadece C++ 11 std özelliklerini kullanarak aynı etkiyi elde etmek için en iyi yolu nedir?C++ 11 std eşdeğeri Boost has_dereference
cevap
Bir sınıfın harici bağımlılıkları olmayan bir işlevi olup olmadığını kontrol etmenin en kolay yolu genellikle void_t
deyimindedir.
// Define this once in your project somewhere accessible
template <class ... T>
using void_t = void;
Bu numara her zaman aynıdır;
template <class T, class = void>
struct has_dereference : std::false_type {};
Bu "son çare" sınıfı şablonu şudur: std::false_type
dan devralan bir sınıf şablonu tanımlar.
template <class T>
struct has_dereference<T, void_t<decltype(*std::declval<T>())>> : std::true_type {};
kullanmak için sadece yapın:: Şimdi sadece tip özelliğine sahiptir zaman istediğimiz çalışan bir ihtisas tanımlayacağız
bool x = has_dereference<int*>::value;
bool y = has_dereference<int>::value;
vb
Ben katacak teknik olarak, operator*
aslında bir fonksiyon ailesidir; Operatör hem nitelikli CV hem de değer kategorisi olabilir. Bir tür üzerinde algılama gerçekleştirdiğinizde, aslında bu aile içinde algılama yapıyorsunuz demektir. Uygulamada nadiren karşılaştığım için daha fazla ayrıntıya girmeyeceğim (operator*
, nadiren kategori niteliğinde niteliklidir ve operatör hemen hemen her zaman bir const versiyonuna sahiptir ve nadiren uçucu), ama şaşırtıcı bir şey gördüğünüzde bunun farkında olmanız gerekir. .
Bu teknik, özellikle de Boost veya Hana gibi bağımlılıklar olmadan meta-programlama yapıyorsanız bunu bilmeye değer. Void_t hakkında daha fazla bilgiyi buradan edinebilirsiniz: How does `void_t` work.
Güzel çalışır. Teşekkür ederim! – andybuckley
Bu, küçük bir SFINAE özelliği yazma yardımcısıdır. Eğer eksikse yeniden oluşturabileceğiniz std::void_t
kullanır.
namespace details {
template<template<class...>class Z, class v, class...Ts>
struct can_apply:std::false_type{};
template<template<class...>class Z, class...Ts>
struct can_apply<Z, std::void_t<Z<Ts...>>, Ts...>:std::true_type{};
}
template<template<class...>class Z, class...Ts>
using can_apply=typename details::can_apply<Z, void, Ts...>::type;
Bunu bir kez yaptınız, sorunlarınız kolay.
template<class T>
using deref_result = decltype(*std::declval<T>());
template<class T>
using can_deref = can_apply<deref_result, T>;
buradaki fikir std::void_t
makine saklamaktır. "Bazı hesaplamaların sonucunu" ifade eden bir özellik yazıyorsunuz ve bundan "hesaplamanın geçerli olduğu" alabiliyoruz. tek satırda yapıyor
namespace details {
template<class...>struct voider{using type=void;};
}
template<class...Ts>
using void_t=typename voider<Ts...>::type;
bazı eski derleyiciler kırar ve 2 çizgi versiyonu olabilir, hem de yeterince kolaydır: gibi
Son derece portatif void_t
görünüyor.
Yakk 'ın değişik bir versiyonu:
template <class...> struct pack {};
namespace detail {
template<template <class...> class Z, class Pack, class = void>
struct can_apply_impl : std::false_type {};
template<template<class...>class Z, class...Ts>
struct can_apply_impl<Z, pack<Ts...>, std::void_t<Z<Ts...>> > : std::true_type {};
}
template<template<class...>class Z, class...Ts>
using can_apply = detail::can_apply_impl<Z, pack<Ts...>>;
- 1. C++ 11 std :: shared_ptr + boost :: serileştirme
- 2. boost :: C++ 11
- 3. vs2012 cl.exe gcc -std = C++ 11 eşdeğeri nedir?
- 4. C++ sarmalayıcı için boost/C++ 11
- 5. -std = C++ 11 ve -std = gnu ++ 11 arasındaki farklar nelerdir?
- 6. C++ 11: std :: function :: target()
- 7. Destek eşdeğeri std :: async()
- 8. g ++ -std = C++ 11, bayrak etkili olmayacak
- 9. Android ndk'de C++ 11 std :: async
- 10. C++ 11 std :: async Android'de NDK çalışmıyor
- 11. C++ 11 internal std :: dize gösterimi (libstdC++)
- 12. C++ 11 std :: vektör eşzamanlı ortamda
- 13. g ++ komut satırında -std = C++ 11 konumu
- 14. C++ 11
- 15. C++ 11/Boost `unordered_map` silme sırasında neden geri dönmez?
- 16. C++ 11
- 17. Android NDK: Hata: -std = C++ 11 veya -std = gnu ++ 11 derleyici seçenekleri ile etkinleştirilmiş olmalıdır.
- 18. C++ 11 standardını kabul etmek scons anlatmak için nasıl bulmak için Yönetmediğim C++ 11 standart
- 19. std :: this_thread * işlevlerini boost :: thread?
- 20. hızlı aralığı (C++ 11)
- 21. C++ 11 - sıralama işlevini
- 22. C++ 11 tuple performansı
- 23. elle istream C++ 11
- 24. C++ 11 Regex Eşleşmesi
- 25. C++ 11 Regex Capture Grupları Adına Göre
- 26. BGL yinelemesini "saf" C++ 11 alternatifi ile köşe üzerinde değiştirin.
- 27. std :: stringstream ile% 02d eşdeğeri?
- 28. C++ 11 kapatma shared_ptr
- 29. Temperlenmiş sendikalar C++ 11
- 30. C++ 11 haritayı başlat
sadece uygulamaya bakmak olmaz mı? –
Lisansı tam olarak bilmiyorum, ancak muhtemelen Boost uygulamasını yapıştırmak için kod yazabilirsiniz.Sadece başlık olmalı ve çok uzun değil. –
@Nicol Sanırım yapmadın mı? ;-) Dahili bir has_prefix_operator.hpp üstbilgisi tarafından kullanılan ve daha sonra yeniden tanımlanmamış olan BOOST_TT_FORBIDDEN_IF gibi gizli (ve karmaşık görünümlü) #defines ile yapılır. Bu yüzden tersine mühendislik yapmak ve kesinlikle sadece Boost kodunun std tabanlı kodlara kopyalanması meselesi değil. – andybuckley