2008-11-09 25 views

Odpowiedz

33
  1. typu bezpieczny printf
  2. przekazywanie dowolnych wielu argumentów konstruktora w Metody fabryczne
  3. Posiadając dowolne klasy bazowe pozwala na umieszczanie i usuwanie przydatnych zasad.
  4. Inicjowanie poprzez przenoszenie heterogenicznych obiektów maszynowych bezpośrednio do kontenera za pomocą konstruktora szablonu variadic.
  5. Posiadanie operatora literackiego , który może obliczyć wartość dla literału zdefiniowanego przez użytkownika (np. "10110b").

próbki do 3:

template<typename... T> struct flexible : T... { flexible(): T()... { } }; 

próbki do 4:

struct my_container { template<typename... T> my_container(T&&... t) { } }; 
my_container c = { a, b, c }; 

próbki do 5:

template<char... digits> 
int operator "" b() { return convert<digits...>::value; } 

Patrz kod przykład: here

+0

nie tylko bezpieczny dla typu printf, ale także bezpieczne funkcje variadyczne? –

2
  • typu bezpieczny printf
+0

Tak, ale wciąż muszę zobaczyć bardzo elegancką implementację tego :-) –

+0

I thi nk ten konkretny przykład jest nieco zdegenerowany. Pamiętaj, że dla każdej instancji kompilator musi utworzyć więcej kodu. czy możesz sobie wyobrazić tworzenie ponad 100 wersji printf dla każdej możliwej kombinacji argumentów? Och, wzdęcie! – shoosh

+2

@Shy: nie, jeśli wszystkie wersje są wbudowanymi owijkami dla * real * printf. – CesarB

2

Umożliwienie rzeczy jak Boost.Function podjąć dowolne numery parametrów

2

Właśnie napisałem o tym, jak zaimplementować wiele interfejsów COM i zachować swój kod kompaktowy i elegancki z szablonami variadic C++ 0x.

0

Wpisz bezpieczeństwo każdego połączenia z dynamicznym numerem argumentu.

+0

Czy możesz być bardziej precyzyjny? – alestanis

1

Zaimplementowałem NDArray (N-wymiarowa tablica) i ma metodę setSizes z variadic liczba argumentów. Użycie argumentów szablonu variadic jest bezpieczniejsze niż używanie argumentów funkcji variadic, ponadto mogę kontrolować liczbę parametrów przekazywanych do tej funkcji w czasie kompilacji tylko z argumentami szablonu variadic.

void setSizes(uintmax_t currentSize) { 
    static_assert(1 == NDimensions, "Invalid count of arguments given to setSizes."); 

    size_ = currentSize; 
    data_ = new NDArrayReferenceType[currentSize]; 
} 

template <typename... Sizes> 
void setSizes(uintmax_t currentSize, Sizes... sizes) { 
    static_assert(sizeof...(Sizes) + 1 == NDimensions, "Invalid count of arguments given to setSizes."); 

    size_ = currentSize; 
    data_ = new NDArrayReferenceType[currentSize]; 

    for (uintmax_t i = 0; i < currentSize; i++) { 
     data_[i]->setSizes(sizes...); 
    } 
} 

Zaimplementowałam również uniwersalne opakowanie konstruktora dla mojego własnego SmartPointera. Zawija on nad wszystkimi zdefiniowanymi przez użytkownika konstruktorami typu surowego wskaźnika.

template <typename TSmartPointer, typename... Args> 
static inline void initialize(TSmartPointer *smartPointer, Args... args) { 
    smartPointer->pointer_ = new typename TSmartPointer::PointerType(std::forward<Args>(args)...); 
    smartPointer->__retain(); 
} 

Kod ten wydaje się być inobvious, jest to część inicjatora w sprytny wskaźnik dla przypadku, czy sprytny wskaźnik powinien automatycznie wywołać konstruktora wskaźnik na nabycie sprytny wskaźnik (RAII). W przypadku klas abstrakcyjnych nie można wywołać konstruktora.

Więc jeśli mam AbstractObject typ, który jest sprytny wskaźnik od klasy abstrakcyjnej, a typ ConcreteObject, który jest sprytny wskaźnik klasy z konstruktora, że ​​trwa dwa ints, mogę napisać następujący kod:

AbstractObject object = ConcreteObject(42, 42); 

to jest jak C# i Java (ale z RAII) i to działa na mnie w C++/GCC 4.8 =)

3

Może rozmowa Andrei Alexandrescu na Going Native 2012 imprezy, będzie zainteresowanie:

Here to vid eo i Here dokumentacji.

0

W innych odpowiedziach wymieniano bezpieczny printf, ale bardziej ogólnie szablony variadyczne można wykorzystać do implementacji funkcji formatowania, które w ogóle nie wymagają podania informacji o typie poprzez specyfikatory formatu. Na przykład, C++ Format library narzędzia formatowania funkcje podobne do Pythona str.format:

fmt::print("I'd rather be {1} than {0}.", "right", "happy"); 

oprócz bezpiecznego printf. Rodzaje argumentów są przechwytywane automatycznie przy użyciu szablonów variadic w C++ 11.

To sprawia printf Specyfikatory jak lld lub notorycznie PRIdPTR niepotrzebne i zamiast

std::printf("Local number: %" PRIdPTR "\n\n", someIntPtr); 

można po prostu użyć

fmt::printf("Local number: %d\n\n", someIntPtr); 

Oświadczenie: Jestem autorem tej biblioteki