2016-11-17 33 views
6

Bir deney olarak C++ uygulamasında Pythons join() yöntemini uygulamaya çalışıyorum. Sonunda işlevi std::string sınıfının bir yöntemi olarak ekleyeceğim, ancak çalışmanın daha öncelikli olduğunu anlıyorum. Ben iterable tipi aslında iterable olmasını sağlamak için herhangi bir yolC++: Yinelenen türün bir işlev parametresi olarak nasıl iletileceği

template<typename Iterable> 
std::string join(const std::string sep, Iterable iter); 

var mı şu şekildedir: Ben fonksiyonu tanımladık? Örneğin. Daha doğrusu bir Iterable olmasındansa Yardımlarınız C'de

+2

Nasıl tanımlarsınız "iterable"? – Galik

+0

@Galik – aydow

+0

üzerinden yineleyebileceğiniz kapsayıcı olarak tanımlayabilirim Bu işlevi nasıl çağırdığınızı gösteren gerçek bir örnek verebilir misiniz? – Galik

cevap

5

++ için bir int veya char ..

Teşekkür almak istemem, biz ön ve sonuna bir yineleyici (neredeyse bir işaretçi) geçmek kopyalamak gerekmez olarak sep, const referans olarak geçirilen gerektiğini

template<typename Iter> 
std::string join(const std::string &sep, Iter begin, Iter end); 

Not: aralık.

Iter'un aslında bir yineleyici olup olmadığı konusunda endişelenmenize gerek yoktur. Bunun nedeni, kodun çalışmazsa, derlenmemesidir. Örneğin

, (bu kötü uygulamasıdır) öylesine gibi uygulamaya varsayalım:

template<typename Iter> 
std::string join(const std::string &sep, Iter begin, Iter end) { 
    std::string result; 

    while (begin != end) { 
     result += *begin; 
     ++begin; 
     if (begin != end) result += sep; 
    } 

    return result; 
} 

Sonra Iter olarak geçirilen tip bir operator++ olması gerekir, bir operator!= ve bir operator*, çalışmak için hangi Bir yineleyicinin iyi anlaşılmış sözleşmesidir.

+1

"(neredeyse bir işaretçi)" .. teknik olarak _could_ bir işaretçi olabilir, ör. char * x = "merhaba"; bana ("", x, x + 5); " – txtechhelp

+0

" un bana katılmasına rağmen pythons sözdizimi, "string" .join (list) 'dır, ben de bunu taklit etmeye çalışıyorum. C++ stili – aydow

+0

ile çakıştığının farkında değil, bunun neden kötü bir uygulama olduğunu açıklayabilir misiniz? – aydow

1

Tüm standart C++ koleksiyonlarının begin() ve end() üye işlevleri vardır. Geçtin argüman koleksiyonu (sizin terminolojisinde - iterable) aslında olduğundan emin olmak için gerçeği faydalanmak olabilecek bazı SFINAE (C++ 11 örnek) tarafından:

#include <array> 
#include <list> 
#include <vector> 
#include <map> 
#include <string> 

template <class Iterable> 
auto join(const std::string sep, const Iterable& iterable) -> decltype(iterable.begin(), iterable.end(), std::string{}) { 
    (void)sep; // to suppress warning that sep isn't used 
    // some implementation 
    return {}; 
} 

int main() { 
    join(";", std::array<int, 5>{}); 
    join(";", std::list<int>{}); 
    join(";", std::vector<float>{}); 
    join(";", std::string{}); 
    join(";", std::map<int, float>{}); 
    //join(";", int{}); // does not compile as int is not a collection 
} 

[live demo]

İlgili konular