2015-08-10 1 views
3

Я хочу реализовать некоторые целочисленные константы, которые зависят от некоторых других целочисленных констант, используя специализированную специализацию, например.Как разбить специализацию шаблона на разные файлы в соответствии со стандартом C++ 11?

//main.cpp 
#include<cstdint> 

template <uint64_t D> struct space_per_element { static const uint64_t bits; }; 

template <> const uint64_t space_per_element<2>::bits = 1; 

int main() { 
    return space_per_element<2>::bits; 
} 

Что отлично компилируется, используя

g++ -std=c++11 main.cpp 

Но как только я пытаюсь разделить его, как это.

//constants.hpp 
#include<cstdint> 

template <uint64_t D> struct space_per_element { static const uint64_t bits; }; 

//constants.cpp 
#include "constants.hpp" 

template <> const uint64_t space_per_element<2>::bits = 1; 

//main.cpp 
#include "constants.hpp" 

int main() { 
    return space_per_element<2>::bits; 
} 

И скомпилируйте его, используя это.

g++ -std=c++11 main.cpp constants.cpp 

Я получаю следующее сообщение об ошибке:

main.cpp: In function ‘int main()’: 
main.cpp:4:11: error: ‘space_per_element’ was not declared in this scope 
    return space_per_element<2>::bits; 
     ^
main.cpp:4:31: error: ‘::bits’ has not been declared 
    return space_per_element<2>::bits; 
          ^
constants.cpp:3:45: error: expected initializer before ‘<’ token 
template <> const uint64_t space_per_element<2>::bits = 1; 

достаточно странно, код работает с

g++ -std=gnu++11 main.cpp constants.cpp 

или

clang -std=c++11 main.cpp constants.cpp 

Мои вопросы сейчас: Какие GNU- расширение используется здесь? Является ли код нарушением стандарта? Если да: как реализовать этот код в нескольких файлах только с использованием стандарта? Будет ли считаться плохой практикой (с точки зрения переносимости) использовать GNU++11, если Clang, похоже, поддерживает тот же код?

+3

Вы должны * объявить * специализацию в заголовке. – Jarod42

+0

Первоначально у меня было содержимое 'constants.cpp' в' constants.hpp'. Это решает ошибку «ожидаемого инициализатора ...», но ошибки в 'main.cpp' остаются. – user1512263

+0

Была ли попытка ответить на вопрос @ Jarod42? Кажется, это не так. – Yakk

ответ

1

Кажется, что были некоторые предварительно скомпилированные заголовки, которые не совпадали с другим кодом, в том же каталоге. После того, как я удалил их (rm *.gch), я смог скомпилировать файлы с помощью g++ -std=c++11 main.cpp constants.cpp.

Так что кажется, что эти два рабочих параметра работали, потому что они не использовали эти предварительно скомпилированные заголовки.

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