2016-06-01 8 views
1

注:以前はこの問題は発生していませんでした。私のto_stringメソッドはうまくいきました。テンプレートのインスタンス化は、私のPointクラスのための適切なオーバーロードを見つけました。しかし、最後のコミットで何かがうまくいかず、あるソースファイルでこのよく知られているエラーメッセージが表示されます(このソースファイルでのみ、mx :: to_string(mx :: Point)はエラーなしで動作します)。私は、これを駄目にする可能性のある行を気付かなかったので、理由が何であるかを理解することができませんでした。テンプレートインスタンシエーションが、ヘッダー間で呼び出されたときにオーバーロードされたストリーム演算子の引数リストと一致できません

Plusは、解決策を見つけることなく、ストリーム演算子のオーバーロードに関するすべての関連する問題を掃討しました。

#ifndef HELPERTYPES_H 
#define HELPERTYPES_H 
#include <iostream> 
#include <cstdint> 
#include <memory> 
#include <sstream> 
#include <string> 

// ... 

namespace mx{ 
template<typename T> 
std::string to_string(const T& val) 
{ 
    std::ostringstream os; 

    os.flags(std::ios::fixed); 
    os.precision(2); 

    os << val; // getting error here as of recently, both in MinGW 4.7.3 and MSVC15 

    return os.str(); 
} 
} 
#endif 

完全なエラーメッセージ:ここ より読み:私は私のto_stringに機能を持た

#ifndef MXBASIC_UTILITIES_H 
#define MXBASIC_UTILITIES_H 
#include <ostream> 
#include <string> 

namespace mx{ 
    class Point; 
} 

class mx::Point 
{ 
public: 
    Point(); 
    Point(int x, int y); 

    int getX() const; 
    int getY() const; 
    int& getX(); 
    int& getY(); 

    //... 
}; 

inline mx::Point::Point() : _x(0), _y(0) {} 
inline mx::Point::Point(int x, int y) : _x(x), _y(y) {} 

inline int mx::Point::getX() const { return _x; } 
inline int mx::Point::getY() const { return _y; } 
inline int& mx::Point::getX() { return _x; } 
inline int& mx::Point::getY() { return _y; } 

// THE OVERLOAD: 

inline std::ostream& operator<<(std::ostream& os, const mx::Point& point){ 
    return os << '(' << point.getX() << ',' << point.getY() << ')'; 
} 

#endif 

helpertypes.hという名前のヘッダファイル:

は、だから私は、ポイントのクラスを持っているpastebin.com/gFdFezrV

MSVC15:

2>c:(...)\classes\helpertypes.h(87): error C2679: binary '<<': no operator found which takes a right-hand operand of type 'const mx::Point' (or there is no acceptable conversion) 2> c:\program files (x86)\microsoft visual studio 14.0\vc\include\ostream(495): note: could be 'std::basic_ostream> &std::basic_ostream>::operator <<(std::basic_streambuf> *)' 2> c:\program files (x86)\microsoft visual studio 14.0\vc\include\ostream(475): note: or 'std::basic_ostream> &std::basic_ostream>::operator <<(const void *)' 2> c:\program files (x86)\microsoft visual studio 14.0\vc\include\ostream(455): note: or 'std::basic_ostream> &std::basic_ostream>::operator <<(long double)' 2> c:\program files (x86)\microsoft visual studio 14.0\vc\include\ostream(435): note: or 'std::basic_ostream> &std::basic_ostream>::operator <<(double)' 2> c:\program files (x86)\microsoft visual studio 14.0\vc\include\ostream(415): note: or 'std::basic_ostream> &std::basic_ostream>::operator <<(float)' 2> c:\program files (x86)\microsoft visual studio 14.0\vc\include\ostream(395): note: or 'std::basic_ostream> &std::basic_ostream>::operator <<(unsigned __int64)' 2> c:\program files (x86)\microsoft visual studio 14.0\vc\include\ostream(375): note: or 'std::basic_ostream> &std::basic_ostream>::operator <<(__int64)' 2> c:\program files (x86)\microsoft visual studio 14.0\vc\include\ostream(355): note: or 'std::basic_ostream> &std::basic_ostream>::operator <<(unsigned long)' 2> c:\program files (x86)\microsoft visual studio 14.0\vc\include\ostream(335): note: or 'std::basic_ostream> &std::basic_ostream>::operator <<(long)' 2> c:\program files (x86)\microsoft visual studio 14.0\vc\include\ostream(315): note: or 'std::basic_ostream> &std::basic_ostream>::operator <<(unsigned int)' 2> c:\program files (x86)\microsoft visual studio 14.0\vc\include\ostream(290): note: or 'std::basic_ostream> &std::basic_ostream>::operator <<(int)' 2> c:\program files (x86)\microsoft visual studio 14.0\vc\include\ostream(270): note: or 'std::basic_ostream> &std::basic_ostream>::operator <<(unsigned short)' 2> c:\program files (x86)\microsoft visual studio 14.0\vc\include\ostream(236): note: or 'std::basic_ostream> &std::basic_ostream>::operator <<(short)' 2> c:\program files (x86)\microsoft visual studio 14.0\vc\include\ostream(216): note: or 'std::basic_ostream> &std::basic_ostream>::operator <<(bool)' 2> c:\program files (x86)\microsoft visual studio 14.0\vc\include\ostream(209): note: or 'std::basic_ostream> &std::basic_ostream>::operator <<(std::ios_base &(__cdecl *)(std::ios_base &))' 2> c:\program files (x86)\microsoft visual studio 14.0\vc\include\ostream(202): note: or
'std::basic_ostream> &std::basic_ostream>::operator <<(std::basic_ios> &(__cdecl *)(std::basic_ios> &))' 2> c:\program files (x86)\microsoft visual studio 14.0\vc\include\ostream(196): note: or 'std::basic_ostream> &std::basic_ostream>::operator <<(std::basic_ostream> &(__cdecl *)(std::basic_ostream> &))' 2> c:\program files (x86)\microsoft visual studio 14.0\vc\include\ostream(692): note: or 'std::basic_ostream> &std::operator <<>(std::basic_ostream> &,const char *)' 2> c:\program files (x86)\microsoft visual studio 14.0\vc\include\ostream(739): note: or 'std::basic_ostream> &std::operator <<>(std::basic_ostream> &,char)' 2> c:\program files (x86)\microsoft visual studio 14.0\vc\include\ostream(777): note: or 'std::basic_ostream> &std::operator <<>(std::basic_ostream> &,const char *)' 2> c:\program files (x86)\microsoft visual studio 14.0\vc\include\ostream(824): note: or 'std::basic_ostream> &std::operator <<>(std::basic_ostream> &,char)' 2> c:\program files (x86)\microsoft visual studio 14.0\vc\include\ostream(950): note: or 'std::basic_ostream> &std::operator <<>(std::basic_ostream> &,const signed char *)' 2> c:\program files (x86)\microsoft visual studio 14.0\vc\include\ostream(957): note: or
'std::basic_ostream> &std::operator <<>(std::basic_ostream> &,signed char)' 2> c:\program files (x86)\microsoft visual studio 14.0\vc\include\ostream(964): note: or 'std::basic_ostream> &std::operator <<>(std::basic_ostream> &,const unsigned char *)' 2> c:\program files (x86)\microsoft visual studio 14.0\vc\include\ostream(971): note: or
'std::basic_ostream> &std::operator <<>(std::basic_ostream> &,unsigned char)' 2> c:\program files (x86)\microsoft visual studio 14.0\vc\include\ostream(981): note: or 'std::basic_ostream> &std::operator <<,mx::Point>(std::basic_ostream> &&,const _Ty &)' 2> with 2> [ 2>
_Ty=mx::Point 2> ] 2> c:\program files (x86)\microsoft visual studio 14.0\vc\include\ostream(1019): note: or
'std::basic_ostream> &std::operator <<>(std::basic_ostream> &,const std::error_code &)' 2> c:\program files (x86)\microsoft visual studio 14.0\vc\include\random(2568): note: or
'std::basic_ostream> &std::operator <<>(std::basic_ostream> &,const std::bernoulli_distribution &)' 2> c:\program files (x86)\microsoft visual studio 14.0\vc\include\thread(246): note: or
'std::basic_ostream> &std::operator <<>(std::basic_ostream> &,std::thread::id)' 2> c:(...)\classes\helpertypes.h(87): note: while trying to match the argument list '(std::ostringstream, const mx::Point)' 2> c:(...)\classes(...)\entity\tinyent\tinyent.cpp(1502): note: see reference to function template instantiation 'std::string mx::to_string(const T &)' being compiled 2> with 2> [ 2> T=mx::Point 2> ]

MinGW 4.7.3:

In file included from jni/../../Classes/utilities/pattern/pat.h:5:0, from jni/../../Classes/(...)/entity/tinyent/../ent.h:3, from jni/../../Classes/(...)/entity/tinyent/tinyent.h:2, from jni/../../Classes/(...)/entity/tinyent/tinyent.cpp:1: jni/../../Classes/helpertypes.h: In instantiation of 'std::string mx::to_string(const T&) [with T = mx::Point; std::string = std::basic_string]': jni/../../Classes/(...)/entity/tinyent/tinyent.cpp:1502:20: required from here jni/../../Classes/helpertypes.h:87:5: error: cannot bind 'std::basic_ostream' lvalue to 'std::basic_ostream&&' os << val; ^In file included from jni/../../Classes/utilities/pattern/abspat.h:6:0, from jni/../../Classes/utilities/pattern/pat.h:3, from jni/../../Classes/(...)/entity/tinyent/../ent.h:3, from jni/../../Classes/(...)/entity/tinyent/tinyent.h:2, from jni/../../Classes/(...)/entity/tinyent/tinyent.cpp:1: C:/Users/(...)/Documents/libs/android-ndk-r10e/sources/cxx-stl/gnu-libstdc++/4.9/include/ostream:602:5: note: initializing argument 1 of 'std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits; _Tp = mx::Point]' operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x) ^

インスタンス化の場所riggered:

代替:

私は右のそれが動作このToString関数の前で私のto_stringに関数の定義を置く場合

#include "tinyent.h" 

// ... 

std::string toString() const 
{ 
    return std::string("TinyEnt ") + mx::to_string(id()) + " at " // decltype(id()) is ULL, no problem here 
     + mx::to_string(mx::Point(_posX, _posY)); // place of instantiation, overload not found 
} 

tinyent.cpp

#pragma once 
#include <string> 
#include "ent.h" 
#include "mxbasic_utilities.h" // definition of my overload included! 

class TinyEnt : public Ent 
{ 
public: 
    // ... 
    virtual std::string toString() const override; 

private: 
    // ... 
    int _posX, posY; 
}; 

tinyent.h tinyent.cpp

#include "tinyent.h" 


template<typename T> 
std::string to_string(const T& val) 
{ 
    std::ostringstream os; 

    os.flags(std::ios::fixed); 
    os.precision(2); 

    os << val; 

    return os.str(); 
} 

std::string toString() const 
{ 
    return std::string("TinyEnt ") + mx::to_string(id()) + " at " 
     + ::to_string(mx::Point(_posX, _posY)); // no problems this way 
} 

私はこれとどうしたらよいか分かりません。多分再帰的な包含があったなら、インクルード のインクルードをチェックしましたが、そうではありません(helpertypes.h はstlヘッダのみに依存します)。私は地面0からの再構築を試みて、別のコンパイラを使ってみました。あなたは何が間違っているかもしれないか何かヒントを持っていますか?

EDIT: 私のMX :: TO_STRING機能で完全な名前空間の資格を使用して(そのような:::operator(os, val);)私は別のエラーメッセージを取得します。このインスタンス化では、引数検索の最初のラウンドで見つけられなかったかのように、size_t(この場合はunsigned int)を与えたときのあいまい性エラーが発生します。

MSVC15およびMinGWによって生成されるエラーメッセージ。 エラー:このセグメントの

In file included from jni/../../Classes/utilities/pattern/pat.h:5:0, from jni/../../Classes/patmgr.h:4, from jni/../../Classes/patmgr.cpp:1: jni/../../Classes/helpertypes.h: In instantiation of 'std::string mx::to_string(const T&) [with T = unsigned int; std::string = std::basic_string]': jni/../../Classes/utilities/pattern/pat_bit_spec.h:185:37: required from here jni/../../Classes/helpertypes.h:94:22: error: call of overloaded 'operator<<(std::ostringstream&, const unsigned int&)' is ambiguous ::operator<<(os, val); ^jni/../../Classes/helpertypes.h:94:22: note: candidates are: In file included from jni/../../Classes/utilities/pattern/pat.h:3:0, from jni/../../Classes/patmgr.h:4, from jni/../../Classes/patmgr.cpp:1: jni/../../Classes/utilities/pattern/abspat.h:72:22: note: std::ostream& operator<<(std::ostream&, AbsPat::Loc) inline std::ostream& operator<<(std::ostream& os, AbsPat::Loc loc) ^jni/../../Classes/utilities/pattern/abspat.h:72:22: note: no known conversion for argument 2 from 'const unsigned int' to 'AbsPat::Loc'

過負荷のコール 'オペレータは< <(STD :: ostringstream &、CONST unsigned int型&)が' 曖昧 ::オペレータ< <(OS、val)です。 ^ これはどうやってあいまいなのでしょうか?

+1

明白なことを確立するには、helperypes.h(まだ)に 'operator <<'定義のヘッダーファイルを含めますか? – Smeeheey

+0

また、 'os << val'行を(完全な名前空間で修飾された)' ms :: operator <<(os、val) 'に変更して、問題がどこにあるのか確認することができます – Smeeheey

+0

helpertypes.hはありませんオーバーロードされた演算子の定義が含まれている必要があります。インスタンス化の仕事です。完全な名前空間はグローバル関数である:: operator <<(os、val)ですが、:: operator <<(os、val)を使用すると、異なるエラーメッセージが表示されます。 – MatrixAndrew

答えて

0

コンパイラは何らかの理由で、グローバル名前空間で定義された自分のオーバーロードをもう考慮しないと考えました。私はその後、友人と同じ名前空間で過負荷を定義しようとしましたが、これらのあいまいエラーが発生しました。曖昧さのエラーが発生したのは、mx :: namespaceではなく、グローバル名前空間に定義されているように、私の過負荷宣言を残したからです。いったん私はフォワード宣言を削除し、コンパイラにADLの力を利用させるようになりました。神のために、コンパイルしました。

グローバルネームスペースのオーバーロードのルックアップがなぜ壊れているのか(そしてなぜ1つのコンパイル単位でしかないのか)は、私にとってはまだまだ謎です。

ストーリーの模範: 私は、クラスが今からのものと同じ名前空間でオペレータオーバーロードを宣言します。

関連する問題