следующим кодом (упрощенная версия моего исходного кода)
#include
#include
template class A; // edit 1 following Mark & Matthieu
template class A {
X a;
template friend class A; // edit 1 following Mark & Matthieu
public:
A(X x) : a(x) {}
X get() const { return a; } // edit 2 to avoid using A::a
template
auto diff(A const& y) const
-> decltype(a - y.a) // original code causing error with gcc
-> typename std::common_type::type // alternative following Rook
-> decltype(this->get() - // edit 3 not using A::a
y.get()) // edit 2 not using A::a
{ return a - y.get(); }
};
template
inline auto dist(A const& x, A const& y) -> decltype(std::abs(x.diff(y)))
{ return std::abs(x.diff(y)); }
int main()
{
A x(2.0), y(4.5);
std::cout << " dist(x,y)=" << dist(x,y) << '\n'; // <-- error here
}
Я получаю следующую ошибку с gcc 4.7.0:
test.cc: In function
decltype (std::abs(x.diff(y))) dist(const A
[с&, const A &) X = double; Y = двойной; decltype (std::abs(x.diff(y))) = double
]':test.cc:5:5: error:
double A
is private::a выделенная строка: error: в этом контексте
Очевидно, что это сообщение об ошибке не очень полезно. Есть ли ошибка в моем коде? Или это проблема с компилятором?
EDIT1: объявление друга не помогло.
EDIT2: отказ от использования A
также не помог.
EDIT3: вместе с EDIT2наконец устранили проблему. decltype()
в определении dist()
требует decltype()
для A
, который, в свою очередь, использовал A
, закрытый в первом контексте.
EDTI4: Предложение Rook по использованию typename std::common_type
также работает!
EDIT5: но см. ответ Джонатана Уэйкли на этот вопрос