2016-05-19 26 views
5

Bazı şablon türlerini dizeye dönüştürmesi gereken şablon kodum var. Bunun için kendi türlerim için to_string'e aşırı yükleniyorum. Ama tür zaten bir dize de olabilir. Daha sonra derleme başarısız olur, çünkü tür dizgisi için to_string fazla yüklenmez (sadece argümanını döndürür).Neden to_string yok (const string &)?

düzenleme: örnek kod:

template<class T> 
class TemplatedClass 
{ 
public: 

string toString() const 
{ 
    // this should work for both simple types like int, double, ... 
    // and for my own classes which have a to_string overload 
    // and also for string, which is the reason for my question 
    return string("TemplatedClass: ").append(to_string(t_)); 
} 

private: 
    T t_; 
}; 
+2

nasıl sorunu çözmek için bize soruyorsunuz ya neden hiçbir aşırı yük arıyoruz edilir? Eski için lütfen MCVE sağlayın. Sonuncusu için, cevap vermek kolay - çünkü bu aşırı yükleme saçma olurdu. – SergeyA

+0

Kendin yazabilir misin? Ayrıca, bu işleç için daha uygun olan ancak daha fazla "deyimsel" olan bazı operatör << veya diğer serileştirme yöntemlerini kullanmak daha iyi olurdu. – rubenvb

+0

Bir dize alan ve dizenin bir kopyasını döndüren 'to_string' işlevine sahip olmak saçma olurdu. Bunu sadece “std :: string” dizgesi ile yapabilirsiniz. Kodunuz "to_string" işlevini kullanıyor gibi görünüyor? – NathanOliver

cevap

7

aşağıdaki gibi sadece uygun aşırı ile kendi şablonu fonksiyonu yazabiliriz:

#include <iostream> 
#include <string> 
using namespace std; 

template<typename T> 
std::string toString(const T& t) { 
    return std::to_string(t); 
} 

std::string toString(const char* t) { 
    return t; 
} 

std::string toString(const std::string& t) { 
    return t; 
} 


int main() { 
    cout << toString(10) << endl; 
    cout << toString(1.5) << endl; 
    cout << toString("char*") << endl; 
    cout << toString(std::string("string")) << endl; 
    return 0; 
} 
+0

Küçük not: Bu SFINAE –

+6

utlizing çalışır @SebastianHoffmann bu hiçbir SFINAE yok. Bir ikame hatası görüyor musunuz? –

+0

@ T.C. Std :: string için şablon örneği bir hata vermeyecek? –

6

Sadece tüm std::to_string ve tüm senin to_stringusing tarafından birleştirebilirsiniz derective. Benim yaklaşımla Eğer const char * için bir aşırı veya bir dizeye dönüştürülebilir olan başka türde gerekmez

#include <string> 
#include <iostream> 

namespace convert { 
    std::string to_string(std::string s) 
    { 
     return s; 
    } 

    template<class T> 
    std::string stringify(T&& t) 
    { 
     using convert::to_string; 
     using std::to_string; 
     return to_string(std::forward<T>(t)); 
    } 
} 

class Foo 
{ 
public: 
    operator std::string() const { return "Foo"; } 
}; 

namespace bar { 
    class Bar 
    {}; 

    std::string to_string(const Bar&) { 
     return "Bar"; 
    } 
} 

int main() 
{ 
    std::string s{"I'm lvalue string"}; 
    std::cout << convert::stringify(42) << "\n"; 
    std::cout << convert::stringify(std::string("I'm string")) << "\n"; 
    std::cout << convert::stringify("I'm c-string") << "\n"; 
    std::cout << convert::stringify(s) << "\n"; 
    std::cout << convert::stringify(Foo{}) << "\n"; 
    std::cout << convert::stringify(bar::Bar{}) << "\n"; 

    return 0; 
} 

Not: Ve kopya sayısını en aza indirmek için değeriyle std::string geçmektedir. Ayrıca bu yaklaşım, bir kullanıcının herhangi bir sınıf için to_string aşırı yükünü eklemesine izin verir (argüman bağımlı arama ile bulunur). değeriyle bir dize kabul ileri optimizasyon convert::to_string için

lvalue ve rvalue aşırı ayrılabilir.

+0

Sadece öneri (ve kullanım durumuna bağlı olarak tamamen geçersiz olabilir), referansların mükemmel iletimini kullanmak için girişi/çıkışı değiştirmek ve daha sonra bu referansları döndürmek olacaktır. Eğer büyükse, o zaman hiçbir tahsis yoktur ve/veya arayan kişinin dizgeyi hareket ettirmek için endişelenmesi gerekmez. 'şablon otomatik to_string (std :: temel_dizleme &&) -> decltype (std :: ilet > (s)) {dönüş s; } ' – Andrew

+0

@Andrew yep, o zaman kontratın ikiliğini gerçekten beğenmeme rağmen bir seçenek. çünkü jenerik 'to_string' bir değer veya ref döndürebilir. Btw 's dönüş ifadesinde iletilmelidir. Ve dönüş için otomatik, dönüşün değerle yapıldığı anlamına gelir. Bunun yerine decltype (auto) 'olmalıdır. – oliora

İlgili konular