2015-07-02 13 views
15

Boş bir başlatıcı listesi ile std::min() çağrılması genellikle derlenmiyor (tüm soru std::max() için aynı şekilde belirtilebilir). Bu kod: clang ileBoş bir başlatıcı listesinde std :: min çağrılıyor (ve açıkça belirtmek tür) tanımlanmamış davranış?

#include <iostream> 
#include <algorithm> 

int main() { 
    std::cout << std::min({}) << "\n"; 
    return 0; 
} 

bu hatayı veriyor:

test.cpp:6:17: error: no matching function for call to 'min' 
    std::cout << std::min({}) << "\n"; 
       ^~~~~~~~ 
algorithm:2599:1: note: 
     candidate template ignored: couldn't infer template argument '_Tp' 
min(initializer_list<_Tp> __t) 

bu durumda izin verilmez neden bu durumda dönmek için mantıklı bir değere üzerinde anlaşmaya zordur çünkü görebilirsiniz . Bununla birlikte, teknik olarak söylenen kod, sadece şablon parametresinin çıkarılamadığı için derleme yapmamaktadır. Ben kodu derler parametresini zorlamak ama bir kilitlenme alırsanız:

#include <iostream> 
#include <algorithm> 

int main() { 

    std::cout << std::min<int>({}) << "\n"; 

    return 0; 
} 

$ clang++ -std=c++11 test.cpp -o test 
$ ./test 
Segmentation fault: 11 

O std::min()std::min_element() açısından uygulanır, çünkü kazasında doğar görünüyor ve boş başlatıcı listesi geçersiz end() yineleyici dereference içine sonuçlanır.

Bu kod undefined davranışı C++ 11/C++ 14 altında mı? std::min(), açık şablon parametreleri olmadan çağrıldığında derlenmemesi belirtiliyor mu? std::min_element() ile uygulanacak şekilde belirtilen std::min() mu?

+0

Özellikle bir şey yapmasını beklemiyordum. – gigabytes

+0

Prensip olarak iyi bir cevap olmadığını kabul ediyorum. Hatta soruda belirtiyorum. Ama onu çağırmanın bir yolu derler ve başka bir şey yapmadığından, derlemenin gerçekten UB olarak tanımlanmış olup olmadığını sordum. – gigabytes

cevap

22

Evet, bu UB. C++ 14 (n4140) başı olarak 25.4.7/4:

template <class T> 
constexpr T min(initializer_list<T> t); 

...

4 Requires:T is LessThanComparable and CopyConstructible and t.size() > 0.

(vurgu madeni)

aynı ifade C++ 11 de bulunur.

+0

Kötü ... Standartlara baktım ve bir sebepten dolayı 't.size()> 0' gereksinimini tamamen kaçırdım! – gigabytes

İlgili konular