2016-04-06 15 views
1

Dize sayısını belirtilen dizinlerde öğeleriyle sıralamak için bir şablon yazıyorum. Çalıştığım bir kod var, ancak kullanmak için bir acı çünkü tuple öğelerini sıralamak için kullanılan ikili işlev türünü belirtmem gerekiyor. Ben doğrusu böyle tekrarından kaçınmak için aşağıdaki gibi bir arayüz olurdu, yerineKısmi şablon türü indirimi

sort_by_index<std::less<char>, 0>(std::less<char>()); 

: Ben başlığın ilk elemana göre sıralamak istiyorsanız

template <typename BinaryFunction, int Index> 
struct sort_by_index_t { 
    explicit sort_by_index_t(const BinaryFunction& binary_function) 
     : binary_function(binary_function) {} 

    template <typename Tuple> 
    bool operator()(const Tuple& left, const Tuple& right) const { 
    return binary_function(std::get<Index>(left), 
          std::get<Index>(right)); 
    } 

private: 
    const BinaryFunction binary_function; 
}; 

template <typename BinaryFunction, int Index> 
sort_by_index_t<BinaryFunction, Index> 
sort_by_index(const BinaryFunction& binary_function) { 
    return sort_by_index_t<BinaryFunction, Index>(binary_function); 
} 

Yani, yazmak zorunda ama şu anda derleme değil.

sort_by_index<0>(std::less<char>()); 

otomatik olarak Index anlamak için bir yol görmüyorum (ve gereksiz olurdu), ancak sort_by_indexBinaryFunction tipini anlamak gerekir.

Yukarıdakileri nasıl yeniden yazabilirim, böylece BinaryFunction türünü belirtmem gerekmez.

cevap

3

Index olmayan deducible olduğunu. Açıkça sağlanan şablon argümanlar sadece temin edilebilir soldan sağa, sadece Index ilk göreceği emin olmak için onları yeniden düzenlemek için basit bir düzeltme yüzden şablon argümanları sıralaması indirimi için önemli değil oysa:

template <int Index, typename BinaryFunction> // only this line needs to change 
sort_by_index_t<BinaryFunction, Index> 
sort_by_index(const BinaryFunction& binary_function) { 
    return sort_by_index_t<BinaryFunction, Index>(binary_function); 
} 

Dedi ki, bu tatmin edici değil çünkü görünüşte birbiriyle alakasız iki şeyi - karşılaştırıcı olarak kullandığımız ikili işlev ve aslında karşılaştırdığımız verileri birleştiriyoruz. Ve burada çok fazla kod yazmamız gerekiyor ki bu sadece tekrarlayan bir boilerplate. 1, ranges proposal, Eric Niebler, Sean Parent ve Andrew Sutton, tartışılabilir projeksiyonlar alan algoritmalar için tartışıyorlar. Bir C++ 14 derleyiciniz varsa, bunları uygulayabilmeniz için onları uygulamanızı öneririm:

// polymorphic getter 
template <size_t I> 
auto getter() { 
    return [](auto&& tuple) { 
     return std::get<I>(std::forward<decltype(tuple)>(tuple)); 
    }; 
} 

// just use the getter as a projection 
std::sort(container_of_tuples, 
    std::less<char>{}, // this is the binary function 
    getter<0>());  // this is the projection 
+0

C++ 'da en iyi kullanıcı olarak, lütfen bana en iyi kitabı öğrenebilirsiniz C++? – Shafizadeh

+2

@Shafizadeh [Definitive C++ Kitap Rehberi ve listesi] (http://stackoverflow.com/q/388242/2069064) – Barry

+0

Ben, ben order_by (projection, base_order = std :: less <>) 'yerine uygulamak projeksiyon desteği ile reimplement 'std :: sort'. – Yakk

0

Şablon türü kesinti sağdan sola doğru çalışır. En sağdaki şablon parametresi belirtilmişse, diğer şablon parametrelerini de içermelidir. Yukarıdaki aşağıdaki hafif değişiklik, daha temiz bir arayüze olanak tanır. Temel olarak,şablon parametresi, sort_by_indexIndex otomatik olarak çıkarılamadığı için BinaryFunction'dan önce gelmelidir.

template <int Index, typename BinaryFunction> 
struct sort_by_index_t { 
    explicit sort_by_index_t(const BinaryFunction& binary_function) 
     : binary_function(binary_function) {} 

    template <typename Tuple> 
    bool operator()(const Tuple& left, const Tuple& right) const { 
    return binary_function(std::get<Index>(left), 
          std::get<Index>(right)); 
    } 

private: 
    const BinaryFunction binary_function; 
}; 

template <int Index, typename BinaryFunction> 
sort_by_index_t<Index, BinaryFunction> 
sort_by_index(const BinaryFunction& binary_function) { 
    return sort_by_index_t<Index, BinaryFunction>(binary_function); 
} 

şimdi derler aşağıda: açıkça sağlanmalıdır, böylece

sort_by_index<0>(std::less<char>()); 
İlgili konular