Farz edelim ki, aynı temel işlevselliği uygulayan, ancak farklı üye işlev adlarına sahip arabirimlere sahip birden çok sınıf için yeniden kullanmak istediğim bazı genel kodlar var. Örneğin, aşağıdaki sınıf, temel sınıfın erase
üye işlevine sahipse, örn. std::set
veya std::unordered_set
.Derleme zamanında C++ 'da bir üye işlevi
template <typename T>
static std::chrono::duration<double> set_insert_time(const typename T::value_type &v) {
T set;
std::chrono::time_point<std::chrono::high_resolution_clock> start, end;
start = std::chrono::high_resolution_clock::now();
set.erase(v);
end = std::chrono::high_resolution_clock::now();
return end - start;
}
Ancak, şimdi bu işlevin örn. Bunun yerine unsafe_erase
adlı bir işlevi sağlayan tbb::concurrent_unordered_set
.
Benim ilk yaklaşma aşağıdakileri tanımlayan ve bunun yerine set_ops<T>::erase(set, v)
arayarak, kısmi şablon uzmanlık tip özelliklerini kullanmayı oldu. tbb::concurrent_unordered_set
templated sınıf değil, bir tür olduğu için ne yazık ki bu derleme değil. Ayrıca anahtar türü için ikinci bir şablon bağımsız değişkenle tipi özelliği genişletmek için çalıştı, ama bu T
std::mem_fn(&T<U>::erase)
bir şablon olmadığı için derlenmeyecektir.
template <typename T>
struct set_ops {
constexpr static auto erase = std::mem_fn(&T::erase);
};
template <>
struct set_ops<tbb::concurrent_unordered_set> {
constexpr static auto erase = std::mem_fn(&T::unsafe_erase);
};
Ayrıca üye işlevini aşağıdaki gibi bir işlev şablonuyla sarmayı denedim. Bu derlenmiş gibi görünüyor, ancak tanımlanmamış referanslar nedeniyle bağlantı kuramıyorsa, ör. decltype ((({parm#1}.erase)({parm#2})),((bool)())) erase<std::set<unsigned int, std::less<unsigned int>, std::allocator<unsigned int> > >(std::set<unsigned int, std::less<unsigned int>, std::allocator<unsigned int> >&, std::set<unsigned int, std::less<unsigned int>, std::allocator<unsigned int> >::key_type const&)
template <typename T>
constexpr auto set_erase(T& s, const typename T::key_type &v) -> decltype(s.erase(v), bool());
template <typename T>
constexpr auto set_erase(T& s, const typename T::key_type &v) -> decltype(s.unsafe_erase(v), bool());
nasıl derleme zamanında bu aliasing uygulanabilir gerekir? Her bir temel sınıf için soyut bir arabirimden miras alan bir uygulama sağlayabileceğimi ya da bir üye işlevine bir işaretçi kullanabileceğimi biliyorum, ancak herhangi bir çalışma zamanı yükünden kaçınmak istiyorum.
gereksiz yere karmaşık görünüyor. "Silme" nin iki sürümü, aşırı yük çözünürlüğü tarafından seçilen ücretsiz işlevler olabilir. – MSalters
@MSalters Ether kısmi uzmanlığı veya 'enable_if' SFINE hileleri. Aksi takdirde, "delete (tbb :: concurrent_unordered_set &, const tbb :: concurrent_unordered_set :: value_type &)' için belirsiz aşırı yüklenmelerle sonuçlanırsınız. –