Decltype и дружественные функции в Visual Studio против G ++

Я писал код на C ++ для векторной математики. Обязательно просто тонкую обертку вокруг std::array пример. Я хотел перегрузить не член begin() функция для возврата итератора в начало резервного массива. Для этого я написал простую функцию друга с auto тип возврата и конечный тип возврата, используя decltype который просто перенаправил вызов в переменную-член.

Это не скомпилируется, и я не мог понять, почему. Я начал возиться с небольшим примером и обнаружил, что следующий код компилируется в G ++ 4.7, но не в последней версии Visual Studio 2012 Professional.

#include <iostream>
#include <array>

template <typename T, size_t size>
class MyClass {

private:
std::array<T, size> elts;

public:
friend auto begin(MyClass &a) -> decltype (std::begin(a.elts)) {
return std::begin(a.elts);
}

};

int main(void) {
MyClass<int, 8> instance;
auto it = begin(instance);
std::cout << *it << std::endl;
return 0;
}

Странно было то, что этот код компилируется только в G ++, если частное объявление elts до объявления begin() функция.

В любом случае, какой компилятор здесь? Visual Studio или G ++?

редактировать: Ошибка компиляции, которую выдал VS2012 error C2228: left of '.elts' must have class/struct/union

6

Решение

Определение шаблона класса MyClass не завершено к тому времени, когда вы используете выражение std::begin(a.elts)Я думаю, у VC есть основания жаловаться. Вы не можете использовать operator . по неполному типу.

В любом случае вы можете обойти это, используя следующее:

#include <iostream>
#include <array>

template <typename T, size_t size>
class MyClass
{
// ...

friend typename std::array<T, size>::iterator begin(MyClass &a)
//     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
{
return std::begin(a.elts);
}
};
7

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector