アプリ版:「スタンプのみでお礼する」機能のリリースについて

UTF-16文字列を扱うためのostreamを用意したいのですが、wcoutの代わりに、unsigned shortを用いたostreamを使いたいと思いました。
そこで、basic_ostreamのクラスのunsigned short型のインスタンスを作ったのですが、以下のエラーが出てしまってコンパイルが出来ませんでした。

「error C2296: '<<' : 無効です。左オペランドには型 'u16ostream (__cde
cl *)(void)' が指定されています。」
「error C2297: '<<' : 無効です。右オペランドには型 'u16char *' が指定
されています。」

コンパイラはVC++2008です。
それとついでですが、通常通りwcoutを使う時みたいに、localeを設定する必要はあるのでしょうか?
回答、よろしくお願いします。


/* 以下ソースコード */
#include <iostream>
typedef unsigned short u16char;
typedef basic_ostream<u16char> u16ostream;

int main()
{
u16ostream ucout();
u16char* str = (u16char*)(L"ああ");

ucout << str << '\n';

return 0;
}

A 回答 (5件)

 こんばんは。


 取りあえず、std::wcout等が書かれたヘッダの中を検索して、見よう見まねでコンパイルには通りました。
 当方はVisualStudio 2008 SP1です。
 まあ、表示がおかしいのですが(typedef wchar_t u16char にすれば普通に表示されます)、以下参考程度に。

#include<iostream>
#include<fstream>
//#include<yvals.h>
#define _cpp_stdout (&(__iob_func())[1])

typedef unsigned short u16char;
typedef std::basic_filebuf<u16char, std::char_traits<u16char> > u16filebuf;
typedef std::basic_ostream<u16char, std::char_traits<u16char> > u16ostream;

int main()
{
u16filebuf ufb(_cpp_stdout);
u16ostream ucout(&ufb);

std::locale::global(std::locale(""));
ucout.imbue(std::locale(""));

ucout << L"ああ";

return 0;
}
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
ただ、yvals.hというヘッダを今改めて探してみた限りでは、該当部分の記述がなぜか見つからなかったですね。ネット上のヘッダのテキストからは見つかりましたが。

とりあえずここからなんとかできるか試してみます。ありがとうございました。

お礼日時:2011/05/16 12:31

「エラーが出る」とだけ言われてもなぁ....


どこで出るのですか?

この回答への補足

u16ostreamクラスの、コンストラクタ呼び出し時です。
具体的には、C = u16char, T = char_traits<u16char>の、

explicit u16ostream() : std::basic_ostream<C, T>
(new basic_streambuf<C, T>) {}

の、basic_streambufをnewする部分です。

補足日時:2011/05/16 12:00
    • good
    • 0

すみません, #1 は (微妙に関係する可能性はあるかもしれないけど) 的を外してますね. #2 がただしい.



んで, デフォルトコンストラクタに template をつけてどうするの?

この回答への補足

再びの回答ありがとうございます。というより、先程の回答の際には何も言わずすみませんでした。


本題ですが、正直、意味も分かっておらずにtemplate付けていました。
しかし、外しても下のエラーが出ますね。

error C2248: 'std::basic_streambuf<_Elem,_Traits>::basic_streambuf' : protected メンバ (クラス 'std::basic_streambuf<_Elem,_Traits>' で宣言されている) にアクセスできません。

また、他にも調べてみたのですが、どうやらbasic_streambufを継承して改良しなければダメなのでしょうか。
coutとかwcoutなどの場合、どういうパラメータを与えてインスタンスを作成してるんでしょうね。標準出力ストリームの機能拡張がしたいわけではないのに……。

補足日時:2011/05/12 18:47
    • good
    • 0

エラーメッセージをよく見ればわかると思いますが...



> u16ostream ucout();

この部分は関数の宣言ですね。
(u16ostream型の返却値を返すucout関数の)

u16ostream型のオブジェクトを作りたいのであれば、

u16ostream ucout;

と書くべきです。

この回答への補足

回答ありがとうございます。

「u16ostream ucout;」としてみましたが、やはりダメです。
http://sato-si.at.webry.info/200502/article_6.html」を参考にして下のようにいじってみましたが、「C2512:既定のコンストラクタが存在しません」と出てしまいますね。


template<class C = u16char, class T = char_traits<u16char> >
class u16ostream : public std::basic_ostream<C, T>{
public:
/* コンストラクタ */
template<class charT, class traits >
explicit u16ostream() : std::basic_ostream<C,T>(new basic_streambuf<C, T>) {}
/* デストラクタ */
virtual ~u16ostream() {}

friend u16ostream& operator<< (u16ostream& stream, const u16char* s);
};

template<class C, class T>
u16ostream<C, T>& operator<< (u16ostream<C,T>& stream, const u16char* s)
{
stream << s;
return stream;
}

補足日時:2011/05/12 13:39
    • good
    • 0

そもそも


「u16ostream を左オペランド, u16char* を右オペランドにとる opeartor<<」
は宣言してあるのですか?

この回答への補足

やっぱり"<<"演算子のオーバーロードが必要なのですか…。
そう思ってu16ostreamを以下のようにもしてみたのですが、エラーは変わらなかったです。


class u16ostream : public std::basic_ostream<u16char>{
public:
friend u16ostream& operator<< (u16ostream& stream, const u16char* s);
};

u16ostream& operator<< (u16ostream& stream, const u16char* s)
{
stream << s;
return stream;
}

補足日時:2011/05/12 12:27
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!