Iterator :: value_typeに基づく関数実装の選択
質問
コンテナの値の種類に基づいてソートアルゴリズムを選択するための合理的な方法を探しています。
現在の形式では、整数/非整数データのために適切なsort(a, b)
を推定できます。
#include <cstdlib>
#include <type_traits>
#include <algorithm>
#include <vector>
#include <iostream>
namespace sort_selector{
template<typename T>
void _radix_sort(T begin, T end){
// radix implementation
}
template<typename T>
typename std::enable_if<
std::is_integral<typename T::value_type>::value>::type
sort(T begin, T end){
std::cout << "Doing radix" << std::endl;
sort_selector::_radix_sort(begin, end);
}
template<typename T>
typename std::enable_if<
!std::is_integral<typename T::value_type>::value>::type
sort(T begin, T end){
std::cout << "Doing sort" << std::endl;
std::sort(begin, end);
}
}
int main(int argc, char** argv) {
std::vector<double> for_stdsort = {1, 4, 6, 2};
std::vector<int32_t> for_radixsort = {1, 4, 6, 2};
//std::array<int32_t, 4> array_for_radixsort = {1, 4, 6, 2};
sort_selector::sort(std::begin(for_stdsort), std::end(for_stdsort));
sort_selector::sort(std::begin(for_radixsort), std::end(for_radixsort));
//sort_selector::sort(std::begin(array_for_radixsort),
// std::end(array_for_radixsort));
return 0;
}
.
- Arrayのようなイテレータを使用できるようにしたいです。(それらは:: value_typeを持っています)。
- Say、Int32_t、Int64_tを区別できるようにしたいと思います。
私はどんな合理的に簡単な方法でもこれを達成する方法として完全に損失しています。即ちすべてのインスタンスに特化していません。
解決
std::iterator_traits<T>::value_type
イテレータの値の種類を取得します。それはポインタとクラスタイプのイテレータのために機能します。
ディスパッチのためには、テンプレートの専門化を使用して適切な実装を選択します(> Live Demo ):
namespace sort_selector {
// Default to using std::sort
template <typename T, typename = void>
struct dispatcher {
template <typename Iterator>
static void sort(Iterator begin, Iterator end) {
std::cout << "Doing std::sort\n";
std::sort(begin, end);
}
};
// Use custom radix sort implementation for integral types
template <typename T>
struct dispatcher<T, typename std::enable_if<std::is_integral<T>::value>::type> {
template <typename Iterator>
static void sort(Iterator, Iterator) {
std::cout << "Doing radix\n";
// radix implementation
}
};
// Use some other specific stuff for int32_t
template <>
struct dispatcher<int32_t, void> {
template <typename Iterator>
static void sort(Iterator, Iterator) {
std::cout << "Specific overload for int32_t\n";
// Do something
}
};
// Dispatch appropriately
template <typename Iterator>
inline void sort(Iterator begin, Iterator end) {
dispatcher<typename std::iterator_traits<Iterator>::value_type>::sort(begin, end);
}
} // namespace sort_selector
.
おそらくsort_selector::sort
を制限する必要があるため、Random Access Iteratorsを必要とするため、エラーメッセージが不可避的に不適切なイテレータの種類を渡しようとしているときに消化されます。
namespace sort_selector {
// Dispatch appropriately
template <typename Iterator>
inline void sort(Iterator begin, Iterator end) {
using traits = std::iterator_traits<Iterator>;
static_assert(
std::is_base_of<
std::random_access_iterator_tag,
typename traits::iterator_category
>::value, "sorting requires random access iterators");
dispatcher<typename traits::value_type>::sort(begin, end);
}
} // namespace sort_selector
. 所属していません StackOverflow