2015-07-02 1 views
15

Вызов std::min() с пустым списком инициализаторов обычно не компилируется (все вопросы могут быть указаны одинаково для std::max()). Этот код:Вызывает std :: min в пустом списке инициализаторов (и явно указывая тип) неопределенное поведение?

#include <iostream> 
#include <algorithm> 

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

С лязгом дает эту ошибку:

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) 

Я могу понять, почему этот случай не будет разрешен, потому что трудно договориться о разумной стоимости, чтобы вернуться в этом случае ,

Однако технически говоря, код не компилируется только потому, что параметр шаблона не может быть выведен. Если я заставляю параметр код компилируется, но я получаю аварию:

#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 

Кажется, возникает сбой, потому что std::min() реализуется в терминах std::min_element() и пустой список инициализатора приводит к разыменованию недействительной end() итератора.

Так что это фрагмент кода неопределенного поведения в C++ 11/C++ 14? Является ли std::min() заявленным не компилировать при вызове без явных параметров шаблона? Является ли std::min() указанным для использования в терминах std::min_element()?

+0

Я не ожидал, что он что-нибудь сделает, в частности. – gigabytes

+0

Я согласен, что в принципе нет хорошего ответа. Я даже заявляю об этом в вопросе. Но так как один способ вызова компиляции, а другой нет, я спросил, действительно ли тот, который компилируется, является UB. – gigabytes

ответ

22

Да, это UB. В соответствии с С ++ 14 (n4140) 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.

(выделено мной)

То же формулировка присутствует в C++ 11, а также.

+0

Мой плохой ... Я посмотрел на стандарт, и по какой-то причине я полностью пропустил требование t.size()> 0'! – gigabytes

Смежные вопросы