次のコードを使用します(元のコードの煮詰めたバージョン)
#include <iostream>
#include <cmath>
template <typename> class A; // edit 1 following Mark & Matthieu
template <typename X> class A {
X a;
template <typename> 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<Y>::a
template <typename Y>
auto diff(A<Y> const& y) const
-> decltype(a - y.a) // original code causing error with gcc
-> typename std::common_type<X, Y>::type // alternative following Rook
-> decltype(this->get() - // edit 3 not using A<X>::a
y.get()) // edit 2 not using A<Y>::a
{ return a - y.get(); }
};
template <typename X, typename Y>
inline auto dist(A<X> const& x, A<Y> const& y) -> decltype(std::abs(x.diff(y)))
{ return std::abs(x.diff(y)); }
int main()
{
A<double> x(2.0), y(4.5);
std::cout << " dist(x,y)=" << dist(x,y) << '\n'; // <-- error here
}
gcc 4.7.0 で次のエラーが発生します。
test.cc: 関数内
decltype (std::abs(x.diff(y))) dist(const A<X>&, const A<Y>&)
[withX = double; Y = double; decltype (std::abs(x.diff(y))) = double
]':test.cc:5:5: エラー:
double A<double>::a
プライベートです強調表示された行: エラー: このコンテキスト内
このエラー メッセージは明らかにあまり役に立ちません。コードにエラーはありますか? それともコンパイラの問題ですか?
EDIT1 : フレンド宣言は役に立ちませんでした。
EDIT2 : 使用を避けることA<Y>::a
も役に立ちませんでした。
EDIT3 : EDIT2 と合わせて、最終的に問題を修正しました。の定義の にはforが必要です。これは、最初のコンテキストでプライベートな を使用します。decltype()
dist()
decltype()
A<X>::diff()
A<X>::a
EDTI4 : Rook の使用の提案typename std::common_type<X,Y>::type
も有効です!
EDIT5 :しかし、この質問に対するJonathan Wakelyの回答を参照してください