私の最後の質問std::common_type<X,Y>::type
への答えとして、可能な場合は、元の の代わりに自動戻り型の宣言で使用することが提案されましたdecltype()
。ただし、そうすると問題が発生しました(gcc 4.7.0を使用)。次の簡単なコードを検討してください
template<typename> class A;
template<typename X> class A {
X a[3];
template <typename> friend class A;
public:
A(X a0, X a1, X a2) { a[0]=a0; a[1]=a1; a[2]=a2; }
X operator[](int i) const { return a[i]; }
X operator*(A const&y) const // multiplication 0: dot product with self
{ return a[0]*y[0] + a[1]*y[1] + a[2]*y[2]; }
template<typename Y>
auto operator*(A<Y> const&y) const -> // multiplication 1: dot product with A<Y>
#ifdef USE_DECLTYPE
decltype((*this)[0]*y[0])
#else
typename std::common_type<X,Y>::type
#endif
{ return a[0]*y[0] + a[1]*y[1] + a[2]*y[2]; }
template<typename Y>
auto operator*(Y s) const -> // multiplication 2: with scalar
#ifdef USE_DECLTYPE
A<decltype((*this)[0]*s)>
#else
A<typename std::common_type<X,Y>::type>
#endif
{ return A<decltype((*this)[0]*s)>(s*a[0],s*a[1],s*a[2]); }
};
int main()
{
A<double> x(1.2,2.0,-0.4), y(0.2,4.4,5.0);
A<double> z = x*4;
auto dot = x*y; // <--
std::cout<<" x*4="<<z[0]<<' '<<z[1]<<' '<<z[2]<<'\n'
<<" x*y="<<dot<<'\n';
}
USE_DECLTYPE
がの場合#defined
、コードは gcc 4.7.0 で正常にコンパイルおよび実行されます。しかし、それ以外の場合、 に示されている行はmain()
乗算 2 を呼び出します。これは、間違っていないにしても奇妙に思えます。これは、使用の結果/副作用である可能性がありますstd::common_type
か、それとも gcc のバグですか?
戻り値の型は、多数の適切なテンプレート関数のどれが選択されるかには関係がないと常に考えていました...