2014-06-05 31 views
6

ben işlev şablon parametresi türü kesinti prosedürü ile ilgili bir sorum var.çaprazlı-init-listeleri ve fonksiyon şablon türü kesinti emri

Bu örneği ele alalım:

#include <vector> 
#include <sstream> 
#include <string> 
#include <iterator> 
#include <fstream> 

int main() 
{ 
    std::ifstream file("path/to/file"); 
    std::vector<int> vec(std::istream_iterator<int>{file},{}); // <- This part 
    return 0; 
} 

Ben doğru şeyleri anlamak durumunda

, ikinci parametre varsayılan yapıcı denir tipine std::istream_iterator olması sonucuna varılmaktadır. Birinci parametre tipi std::istream_iterator<int> ikinci parametre çok std::istream_iterator<int> olarak çıkarılır ve böylece homojen bir başlatma semantik uygulanabilir olarak çıkarılır yana

template <class InputIterator> 
     vector (InputIterator first, InputIterator last, 
       const allocator_type& alloc = allocator_type()); 

:

uygun std::vector yapıcı

olarak bildirilir. Hakkında hiçbir fikrim yok ne tür bir kesinti gerçekleşir. Bu konuda bazı bilgileri takdir ediyorum.

Şimdiden teşekkürler!

+0

Çalışıyor mu? Eğer öyleyse ilk önce düşülmelidir. – Dani

cevap

9

en daha basit bir örnek verelim:

template<class T> 
void foo(T, T); 

foo(42, {}); 

işlev çağrısı, iki bağımsız değişkeni vardır: tip int (değişmez bir tam sayı)

  • bir çaprazlı-init

    • bir prvalue ifade -list{}
    Ikincisi, {}, bir ifade-listesinin bir parçası olabilir, ancak bir ifade kendisi değil. Bir ifade listesi bir başlatıcı listesine olarak tanımlanır. hazırladı-init-listeleri bir türü yoktur.

    Şablon türü kesinti her bir işlev parametresi ayrı ayrı [temp.deduct.type]/2 için yapılır. [Temp.deduct.call] işlev parametresi P için tür kesinti ilgili/1 durumları: P referansları ve ev-eleme çıkarma

    ise ve bazı 'P>' std::initializer_list<P verir argüman, bir başlatıcı listesidir, daha sonra, P ' işlev şablon parametresi olarak türünü ve başlatıcı öğesini argüman olarak alarak, başlatıcı listesinin her elemanı için kesinti yapılır. Aksi takdirde, başlatıcı listesi bağımsız değişken parametresi olmayan çıkarılabilir içerik olarak neden olur. [vurgu benim]

    Yani çağrı foo(42, {}); yılında T ikinci argüman {} çıkarılabilir edilmeyecektir. Bununla birlikte, ilk argümandan T çıkarılabilir.

    Genel olarak, çoklu fonksiyon parametrelerinden T sonucunu çıkarabiliriz. Bu durumda, çıkarılan türler tam olarak [temp.deduct.type]/2 ile eşleşmelidir. Türün yalnızca bir işlev parametresinden çıkarıldığı, ancak başka bir yerde kullanıldığı durumlarda (çıkarım dışı bir bağlamda, dönüş türünde vb. Başka bir işlev parametresinde) sorun yoktur. Tür indirimi başarısız olabilir örn. Bir şablon parametresi herhangi bir işlev parametresinden çıkarılabilir ve açık olarak ayarlanmadığında. iki bağımsız 42 ve {} ile çağrılabilir

    void foo<int>(int, int); 
    

    Bu fonksiyon: düşüldükten sonra

    , T benzer bir işlev imza üretmek, int ile ikame edilecektir. İkincisi, ikinci parametrenin bir değer başlatmasına yol açan bir kopya listesi başlatmasını gerçekleştirecektir.

  • +0

    Bu, sezgisel olarak ne kadar az görüyordu. İşleri temizlediğiniz için teşekkürler. – Veritas