2012-12-14 14 views
5

Obecnie mam szablon funkcji takiego, który konwertuje vector w string (właśnie naturalny ciąg, oddzielając elementy przecinkami):Lepszy sposób egzekwowania tego szablonu?

//the type T must be passable into std::to_string 
template<typename T> 
std::string vec_to_str(const std::vector<T> &vec); 

Jak widać, ta jest przeznaczona tylko dla wektorów którego elementy mogą być przekazywane do wbudowanego std::to_string funkcji (takich jak int, double, etc.)

jest uważany za dobrą praktykę, aby dokument z uwagami dozwolony T? Jeśli nie, co powinienem zrobić? Czy można to wymusić w lepszy sposób?

+0

Oczywiście, można nawet wybrać, aby dokument z uwagami i egzekwowania techniką SFINAE. – aschepler

Odpowiedz

2

Od std::to_string jest C++ 11 cecha, myślę, może być otwarty do C++ 11 roztworze. W tym konkretnym przypadku można skorzystać z tyłu typ zwracany w sfinae sposób:

template <typename T> 
auto vec_to_str(const std::vector<T>& vec) -> decltype(std::to_string(std::declval<T>())); 

które nie zastępują (i wyeliminować to przeciążenie) jeżeli wartość typu nie zadziała to_string. Ale nadal nie jest to najbardziej przyjemny sposób udokumentowania i egzekwowania reguły. Prawdopodobnie istnieje również wersja z powyższej sztuczki Sfinae sprzed wersji C++ 11, ale nie będzie ona wcale ładniejsza.

Ogólnie rzecz biorąc, chciałbym powiedzieć, że wystarczy po prostu udokumentować to w komentarzach (prawdopodobnie przy pomocy znacznika doxygen, np. \tparam). Mógłbyś użyć mechanizmu sprawdzania koncepcji w stylu Boost.Concept-Check, jeśli chcesz.

Na marginesie, w tym konkretnym przypadku, mogę polecić, że można polegać na std::ostreamoperator << zamiast funkcji to_string, ponieważ jest to bardziej prawdopodobne, że typy niestandardowe (np wektorowej 2D lub coś) będzie wyposażony z przeciążeniem do wysyłania do strumienia.

0

Do concepts dotrzeć, można skorzystać z anonimowego decltype parametru type:

template<typename T, 
    typename = decltype(std::to_string(std::declval<T>()))> 
std::string vec_to_str(const std::vector<T> &vec); 
4

Z static_assert i niektóre wypowiedzi SFINAE można spędzić miło czas kompilacji komunikat o błędzie:

template<typename T> 
constexpr auto allowed(int) -> decltype(std::to_string(std::declval<T>()), bool()) 
{ 
    return true; 
} 

template<typename> 
constexpr bool allowed(...) 
{ 
    return false; 
} 

template<typename T> 
std::string vec_to_str(const std::vector<T>& vec) 
{ 
    static_assert(allowed<T>(0), "Invalid value type."); 
    return ""; 
} 

struct foo {}; 

int main() 
{ 
    std::vector<int> v_int; 
    vec_to_str(v_int); 

    std::vector<foo> v_double; 
    vec_to_str(v_double);  // static_assert fires here 
} 
Powiązane problemy