2013-11-15 2 views
2
#include <cstddef> 
#include <iostream> 

template<std::size_t R, std::size_t C> 
struct foo {}; 

template<std::size_t R, std::size_t C> 
class bar { 
public: 
    bar(const foo<R, C>& = foo<R, C>()) {} 
}; 

int main() { 
    bar<10, 10> y; 
    std::cout << 'x'; 
} 

Приведенный выше код compiles and runs correctly (печать x в качестве вывода) на г V4.8 ++, в то время как та же does not even compile на Clang v3.4 ++, требуя в error: unknown type name 'C'. Почему результат компиляции отличается от двух версий?Почему clang ++ не компилирует тот же файл, что и g ++?

Команды, используемые для компиляции являются:

g++-4.8 -std=c++11 -O2 -Wall -pedantic -pthread main.cpp && ./a.out 
clang++ -std=c++11 -O2 -Wall -pedantic -pthread main.cpp && ./a.out 
+2

По крайней мере, вы должны указать заголовок, где определен 'std :: size_t'. – juanchopanza

+0

@juanchopanza, абсолютно верно, исправлено. (проблема, конечно, все еще там) – Shoe

+1

Похож на ошибку компилятора – uk4321

ответ

2

Это дефект в стандарте, обрабатываются как http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#325.

Проблема заключается в том, что поиск по умолчанию в аргументах по умолчанию в классах должен учитывать все члены класса (включая объявленные позже члены класса), но когда аргумент по умолчанию равен T<X, Y>, мы знаем только, что аргумент по умолчанию, когда мы полностью разобрались класс (аргумент по умолчанию может быть T<X, Y> или может быть T<X, с запятой, заканчивающей аргумент по умолчанию, если T не является шаблоном в полной области действия класса).

При работе над этой проблемой GCC и Clang, по-видимому, используют разные подходы к этому. Вы можете просто исправить свой код, заключая в скобки аргумент по умолчанию.

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