2014-02-06 2 views
2

Complete (не) рабочий пример:GCC 4.7 не удается использовать указатель параметра шаблона иногда

struct s { int i; }; 

template<const s* _arr> 
class struct_array 
{ 
public: 
    static constexpr auto arr = _arr[0]; // works 
    template<int > 
    struct inner // line 9, without this struct, it works 
    {  
    }; 
}; 

constexpr const s s_objs[] = {{ 42 }}; 

int main() 
{ 
    struct_array<s_objs> t_obj; 
    return 0; 
} 

Составитель так:

g++ -std=c++11 -Wall constexpr.cpp -o constexpr 

я получаю запущенную программу с GCC ideone в 4.8.1, но 4.7.3 отпечатывает это мне:

constexpr.cpp: In instantiation of ‘class struct_array<((const s*)(& s_objs))>’: 
constexpr.cpp:18:30: required from here 
constexpr.cpp:9:16: error: lvalue required as unary ‘&’ operand 
constexpr.cpp:9:16: error: could not convert template argument ‘(const s*)(& s_objs)’ to ‘const s*’ 

Последние две строки повторяются 3 раза. В чем причина, и есть ли способ обхода моего кода на gcc 4.7.3?

+0

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

ответ

1

Это похоже на ошибку компилятора.

Я пытался вам пример на GCC 4.1.2 (codepad), и вы должны явно отметить переменную как имеющие внешние связи (Const подразумевают внутреннюю связь, если не указано иное, то следующий код C++ 03):

struct s { int i; }; 

template<const s* _arr> 
class struct_array 
{ 
public: 
    static const s arr; 
    template<int > 
    struct inner 
    {  
    }; 
}; 

template<const s* _arr> 
const s struct_array<_arr>::arr = _arr[0]; 

// Notice the 'extern' 
extern const s s_objs[] = {{ 42 }}; 

int main() 
{ 
    struct_array<s_objs> t_obj; 
    return 0; 
} 

У меня также есть работающий на gcc 4.8.1 without C++ 11 включен.

Таким образом, временное решение:

изменение

constexpr const s s_objs[] = ...; 

в

extern const s s_objs[] = ...; 

Live example here.

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

struct data 
{ 
    static const s s_objs[1]; 
}; 

extern const s data::s_objs[1] = {{ 42 }}; 

Это дает мне warning on gcc 4.7, а не на 4,8. Также это doesn't compile on Rise4Fun. Итак, я не уверен, является ли это чистым стандартом или ошибкой в ​​одном из компиляторов.

+0

Ничего себе, спасибо! Каким будет объявление, если 's_objs' должно быть статическим членом класса (некоторого класса) вместо глобальной переменной? Возможно ли это? Мой компилятор говорит, что 'extern' и' static' были конфликтующими ... – Johannes

+0

Мне удалось сделать это с помощью gcc 4.7, но не против. См. Мое редактирование. – Synxis

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