2011-01-23 3 views
1

Я просто потратил пару часов на отладку ошибки компилятора, которую я мог бы установить немедленно, если сообщение об ошибке компилятора было более полезным.Unhelpful (может быть, неправильно?) Gcc сообщение об ошибке

Я свел его к простому примеру:

template <typename T> 
int f(int); 

template <typename U> 
auto g(U x) -> decltype(f(x)); 

int main() 
{ 
    g(0); 
} 

Ошибка:

test.cpp: In function 'int main()': 
test.cpp:9:8: error: no matching function for call to 'g(int)' 
test.cpp:9:8: note: candidate is: 
test.cpp:5:29: note: template<class U> decltype (f(x)) g(U) 

Является ли эта ошибка не в лучшем вводящим в заблуждение, а в худшем, прямо не так? Как я вижу это, проблема не, что данное определение g не является совпадением для вызова, но это определение неверно (поскольку в выражении f (x) в объявлении оно пытается вызвать f без указания параметра шаблона f).

не намного разумнее сообщение об ошибке будет ли это что-то вроде:

no matching function for call to 'f(int)' in 'decltype(f(x))' 
in instantiation of 'g(U)' with U = int 

или даже лучше:

failed to deduce template parameter 1 in call to 'f(int)' in 'decltype(f(x))' 
in instantiation of 'g(U)' with U = int 

я ожидал бы что-то подобное ...

+0

Какую версию GCC, на какой платформе? Это расширение G ++ или синтаксис new-to-C++ 0x? Учитывая использование 'auto', я думаю, последнее. –

+0

@Jonathan: тип decltype и поздний тип возвращаемого значения являются новыми для C++ 0x (следовательно, тег C++ 0x для этого вопроса). Они поддерживаются gcc с (по крайней мере) версии 4.4. Процитированная мной ошибка производится экспериментальной сборкой gcc 4.6, но 4.4 и 4.5 дают аналогичные ошибки. – HighCommander4

+0

GCC 4.5.2, скомпилированный на MacOS X 10.6.6 с компиляцией с 'g ++ -std = C++ 0x -c xx.cpp' дает более простые - менее информативные ошибки:' xx.cpp: In function 'int main() ': 'и' xx.cpp: 9: 8: error: нет соответствующей функции для вызова' g (int) ''. Я думаю, это означает, что вы используете другую версию G ++ - возможно, более новую. –

ответ

1

Вы скорее всего, попадают в правила расширенного SFINAE в C++ 0x; поскольку вызов f(x) не работает в экземпляре возвращаемого типа g (из-за невозможности вывести T для вызова f), g имеет недопустимый тип возврата и, таким образом, будет удален из режима перегрузки. Это особенность, несмотря на ее вред качеству сообщений об ошибках, поскольку компилятор предполагает, что g - это несвязанная функция, которую вы не собираетесь называть. В этом случае нет других перегрузок g, поэтому компилятор должен дать лучшее сообщение.

Дополнительная информация о расширенном SFINAE доступна по адресу http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2634.html.

+0

Что вы подразумеваете под «компилятор предполагает, что g - это несвязанная функция, которую вы не собираетесь называть»? – HighCommander4

+0

Я пытался объяснить причины новых правил SFINAE - чтобы предотвратить ложные ошибки от случайного попадания в перегрузку, которая не должна была называться. Это рассуждение не применяется в этом случае; новые правила ухудшают сообщение об ошибке, не принося никакой пользы. –

1

С Clang я получаю эту ошибку

C:\Users\SUPER USER\Desktop>clang++ -cc1 -std=c++0x aa.cpp 
aa.cpp:9:5: error: no matching function for call to 'g' 
    g(0); 
    ^
aa.cpp:5:6: note: candidate template ignored: substitution failure [with U = int 
] 
auto g(U x) -> decltype(f(x)){} 
    ^
1 error generated. 

гораздо легче понять, чем ошибка, полученного по г ++