2013-06-06 12 views
5

Wczoraj w trakcie odpowiadania na czyjeś pytanie byłem zaskoczeni odkryciem, że GCC 4.7.2 <type_traits> zawierał cecha szablon std::is_explicitly_convertible<From,To> zdefiniowane jako odwrotność std::is_constructible_convertible<To,From>:"static_cast <To> (od)" if i only if "To to {from}", czy też nie?

/// is_explicitly_convertible 
template<typename _From, typename _To> 
struct is_explicitly_convertible 
: public is_constructible<_To, _From> 
{ }; 

Poszukiwanie papieru szlaku , Wtedy odkryłem, że ta cecha nie powinna być tam. A bug został podniesiony przed włączeniem go do tej wersji biblioteki standardowej C++ 11 i został usunięty w gcc 4.8.0.

Sprawozdanie bug wskazał, że std::is_explicitly_convertible (o mandat we wcześniejszych wersjach C++ 0x standard), został usunięty z projektu normy przez N3047 w 2010.

N3047 wyjaśnia about- kolei:

Pozostaje pytanie, w jaki sposób należy również naprawić tę cechę, która ma wpływ na is_explicitly_convertible. Podstawowe wybory są:

  1. Fix is_explicitly_convertible wracając do bieżącego static_cast wypowiedzi, nie czyniąc is_explicitly_convertible zależny od is_constructible.
  2. Usunąć is_explicitly_convertible ze standardu.

Wybrano pierwszy wybór, ale okazało się, że istnieją zupełnie inne rozumienia tego, co w rzeczywistości oznacza "jawnie wymienialny". Podczas gdy niektórzy uważają, że static_cast poprawnie to wyraża, inni uważali, że poprawiony is_constructible zapewnia również lepsze znaczenie dla is_explicitly_convertible. Dlatego niniejszy dokument zaleca usunięcie is_explicitly_convertible z roboczej wersji roboczej. Nie powinno to teraz szkodzić, ponieważ nic nie zależy od tej specjalnej definicji. A jeśli się okaże, że cecha nadal będzie przydatna, może być dodana w innej wersji standardu.

To wyjaśnienie wydaje się sugerować, że strony sporu wiedział przypadkach, w których na wyrażeniu from typu From, static_cast<To>(from) byłoby kompilacji podczas To to{from}; nie będzie; lub odwrotnie.

Czy są takie przypadki?

Jeśli nie, może ktoś autorytatywnie (nie spekulacyjnie, proszę) wyjaśnić rozróżnienie między static_castibility z From do To i constructibility z To z From który był w grają?

+2

* nie * użyć 't do { from} 'w kodzie ogólnym - może dać bardzo różne wyniki do' T na (od); '. – Xeo

+0

Czy możesz wskazać mi gdzieś, co to ilustruje? –

+1

Pomyśl 'std :: vector ' na przykład - 'T na {10}' da wektor jednoelementowy, podczas gdy 'T t (10)' da wektor 10 elementów. – Xeo

Odpowiedz

2

Najpierw trochę kodu testowego.TestA jest wyraźnej konstrukcji, a TestB to wyraźny static_cast ing:

template<typename To, typename From> 
To TestA(From from) { 
    To to{from}; 
    return to; 
} 
template<typename To, typename From> 
To TestB(From from) { 
    return static_cast<To>(from); 
} 

static_cast umożliwia rzutowanie w dół w heirarchy obiektu, natomiast wyraźny konstrukcja nie:

struct Base {}; 
struct Derived:Base {}; 

int main() { 
    Base* b; 
    // TestA<Derived*>(b); -- fails to compile 
    TestB<Derived*>(b); 
} 
+0

Rzeczywiście! Dziękuję Ci. –

Powiązane problemy