0

オーバーロードされた入力/出力演算子を含むカスタム クラスで boost::lexical キャストを使用すると、Max OSX でコンパイルするとあいまいなオーバーロードされた operator>> が発生します。この場合、Boost 1.59 は Macports を使用してインストールされました。

以下は、エラーと目的の結果の両方を示す自己完結型の例です。

#include <iostream>
#include <string>
#include <sstream>
#ifdef __DEMO__
#include <boost/lexical_cast.hpp>
#endif

using namespace std;

enum BoolYN_ENUM { FALSE_YN, TRUE_YN, UNSET_YN};

class BoolYN{
public:
  BoolYN() : _dat(UNSET_YN){}
  BoolYN(const BoolYN& o) : _dat(o._dat) {}

  BoolYN& operator=(const BoolYN_ENUM& val){ _dat = val; return *this;}
  BoolYN& operator=(const BoolYN& o){ _dat = o._dat; return *this;}

  operator const char*() const{
    switch(_dat){
    case FALSE_YN:
      return "F";
    case TRUE_YN:
      return "T";
    default:
      return "U";
    }
  }

  operator int() const {return _dat;}

private:
  BoolYN_ENUM _dat;
};

istream& operator>>(istream& is, BoolYN& obj){
  string token;
  is >> token;
  if(token.size() > 0){
    char s = token[0];
    if(s == 'Y' || s == 'y'){
      obj = TRUE_YN;
    } else if (s == 'N' || s == 'n') {
      obj = FALSE_YN;
    } else {
      obj = UNSET_YN;
    }
  } else {
    obj = UNSET_YN;
  }
  return is;
}

ostream& operator<<(ostream& os, BoolYN& obj){
  os << (const char*) obj;
  return os;
}

int main(int argc, char** argv){

  for(int i=1; i<argc; i++){
    string argi(argv[i]);
#ifndef __DEMO__
    stringstream ss(argi);
    BoolYN boolval;
    ss >> boolval;
#else
    BoolYN boolval = boost::lexical_cast<BoolYN>(argi);
#endif
    cout << "Argument " << i << ": " << boolval << endl;
  }
  return 0;
}

目的の動作を説明するには、適切なインクルード パスを使用してコンパイルするだけです。引数はコマンド ラインで指定され、オーバーロードされた << および >> 演算子を使用して適切に解析されます。

$ g++ main.cpp
$ a.out Yes No IDK
Argument 1: T
Argument 2: F
Argument 3: U

代わりに boost::lexical_cast を使用するには、「-D__DEMO__」でコンパイルすると、次のエラーが発生するはずです。

In file included from main.cpp:6:
In file included from /opt/local/include/boost/lexical_cast.hpp:32:
In file included from /opt/local/include/boost/lexical_cast/try_lexical_convert.hpp:35:
In file included from /opt/local/include/boost/lexical_cast/detail/converter_lexical.hpp:39:
In file included from /opt/local/include/boost/type_traits/has_right_shift.hpp:43:
/opt/local/include/boost/type_traits/detail/has_binary_operator.hpp:158:70: error: use of overloaded operator '>>' is ambiguous (with operand types 'std::__1::basic_istream<wchar_t>' and 'BoolYN')
   BOOST_STATIC_CONSTANT(bool, value = (sizeof(s_check(((make<Lhs>() BOOST_TT_TRAIT_OP make<Rhs>()),make<has_operator>())))==sizeof(::boost::type_traits::yes_type)));

... (very long error msg. truncated) ...

このコードは、Linux、Boost v. 1.51 で "-D__DEMO__" の有無にかかわらず機能します。アイデアやヒントをいただければ幸いです。

4

1 に答える 1

1

それを正確に分析する環境があなたにはありません。operator>>ただし、 lexical_cast 実装によって渡される最初の引数では一致がより良く、(当然のことながら) 引数では一致がより悪いライブラリ候補があるようBoolYNです。特に、診断のオペランドの型はbasic_stream<wchar_t>であるのに対し、あなたoperator>>istream(basic_istream<char>だと思います) を取ることに注意してください。operator>>したがって、ストリームの文字タイプをテンプレート パラメータとしてテンプレートを作成することで、これを解決できる可能性があります。

于 2015-09-04T18:25:04.090 に答える