C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[14]: 型指定子を認識してくれない


(過去ログ 45 を表示中)

[トピック内 29 記事 (1 - 20 表示)]  << 0 | 1 >>

■24045 / inTopicNo.1)  型指定子を認識してくれない
  
□投稿者/ ネタ好き (577回)-(2008/08/27(Wed) 09:12:46)

分類:[C/C++] 

いつもお世話になっています。Boostを学習中またもや問題にぶち当たってしまいました。
次のサンプルコードでエラーが発生します。
※開発環境はVC++2008Expressです。

#include <string>
#include <boost/call_traits.hpp>

using namespace std;

template<typename T>
class Holder
{
public:
	Holder::Holder() {}
	boost::call_traits<T>::param_type Holder::get() { return data; } //ここが怪しい
	void Holder::set( boost::call_traits<T>::param_type d ) { data = d; }

private:
	T data;
};

int main()
{
	Holder<int> hint;
	hint.set( 100 );
	int t = hint.get(); // getやsetは const int で受け渡し

	Holder<string> hstr;
	hstr.set( "hoge" );
	string s = hstr.get(); // getやsetは const string& で受け渡し

	return 0;
}


出力されるエラーは次の通りです。

エラー	2	error C2143: 構文エラー : ';' が 'Holder<T>::get' の前にありません。call_traits.cpp	11
エラー	3	error C4430: 型指定子がありません - int と仮定しました。メモ: C++ は int を既定値としてサポートしていません	call_traits.cpp	11
エラー	4	fatal error C1903: 直前のエラーを修復できません。コンパイルを中止します。	call_traits.cpp	11


私が思うに、型指定子に指定したboost::call_traits<T>::param_typeが認識されていないのが問題だと思いましたので、インクルードのパス指定をBoostがトップになるように指定しました。
それでも上記のエラーが出力されます。
このエラーを解決する方法をご存じの方、もしくは気付いた点がある方は教えて下さい。
お手数ですがよろしくお願いいたします

引用返信 編集キー/
■24047 / inTopicNo.2)  Re[1]: 型指定子を認識してくれない
□投稿者/ シャノン (589回)-(2008/08/27(Wed) 09:53:08)
2008/08/27(Wed) 09:54:39 編集(投稿者)

No24045 (ネタ好き さん) に返信
> 私が思うに、型指定子に指定したboost::call_traits<T>::param_typeが認識されていないのが問題だと思いましたので、インクルードのパス指定をBoostがトップになるように指定しました。
> それでも上記のエラーが出力されます。
> このエラーを解決する方法をご存じの方、もしくは気付いた点がある方は教えて下さい。

typename が要るとか?
typename boost::call_traits<T>::param_type Holder::get() { return data; }
にしないと、param_type が型名だってことがわかんないんじゃなかったかな?
引用返信 編集キー/
■24048 / inTopicNo.3)  Re[2]: 型指定子を認識してくれない
□投稿者/ ネタ好き (578回)-(2008/08/27(Wed) 09:59:24)
No24047 (シャノン さん) に返信

シャノンさんアドバイス有難うございます。
早速やってみました。すると、今度は次のエラーが出力されました。

error C2061: 構文エラー : 識別子 'param_type'

構文エラー????
型と認識してくれたと思うのですが今度は構文エラーorz

申し訳ございませんが、今度はこの構文エラーについて心当たりのある方アドバイスを下さい。
引用返信 編集キー/
■24051 / inTopicNo.4)  Re[3]: 型指定子を認識してくれない
□投稿者/ 774RR (211回)-(2008/08/27(Wed) 10:20:54)
・クラス定義中にインラインでメンバ関数を実装する場合はクラス名修飾は要らない
・別テンプレート中で定義されている型を使う場合は typename が必須になった

template<typename T> class Holder {
public:
    Holder() {}
    typename boost::call_traits<T>::param_type get() { return data; } //ここが怪しい
    void set( typename boost::call_traits<T>::param_type d ) { data = d; }
private:
    T data;
};

でもこの程度であれば T get() { return data; } で必要十分だったりするわけだが・・・

引用返信 編集キー/
■24052 / inTopicNo.5)  Re[1]: 型指定子を認識してくれない
□投稿者/ シャノン (592回)-(2008/08/27(Wed) 10:27:20)
No24045 (ネタ好き さん) に返信
このサンプルですな。
http://www.kmonos.net/alang/boost/classes/call_traits.html
引用返信 編集キー/
■24054 / inTopicNo.6)  Re[2]: 型指定子を認識してくれない
□投稿者/ ネタ好き未記入 (52回)-(2008/08/27(Wed) 11:14:45)
2008/08/27(Wed) 11:15:04 編集(投稿者)

No24051(774RRさん)に返信
私もそう思ってTにしてみたのですが、やはり・・・

error C2061: 構文エラー : 識別子 'param_type'

とエラーが出力されます。


No24052 (シャノン さん) に返信
> ■No24045 (ネタ好き さん) に返信
> このサンプルですな。
> http://www.kmonos.net/alang/boost/classes/call_traits.html

その通りです。
引用返信 編集キー/
■24055 / inTopicNo.7)  Re[3]: 型指定子を認識してくれない
□投稿者/ あんどちん (7回)-(2008/08/27(Wed) 11:41:23)
No24054 (ネタ好き未記入 さん) に返信

get/set 両方にtypename付けたら通るんじゃないかな?

それから、T getだと自動で参照型にしてもらえる旨味がなくなっちゃう
引用返信 編集キー/
■24056 / inTopicNo.8)  Re[4]: 型指定子を認識してくれない
□投稿者/ 774RR (212回)-(2008/08/27(Wed) 11:56:13)
俺 24051 のコードがコンパイル通るのは確認済みなので (HPUX+gcc-4.2.2+boost_1_35_0)
コピペして味噌 (get/set 両方にきっちり typename 書いてあるよ)

自動的に参照型になるあたりは御意。
最近組み込み系しか使ってないので勘がにぶっとるなぁ
引用返信 編集キー/
■24057 / inTopicNo.9)  Re[5]: 型指定子を認識してくれない
□投稿者/ ネタ好き (579回)-(2008/08/27(Wed) 12:09:00)
2008/08/27(Wed) 12:09:22 編集(投稿者)

No24055(あんどちんさん)に返信
教えて頂き有難うございます。なるほど、両方につけるところがポイントなんですね。
getにエラーが出るのでgetばかり見ていました。
今度からはもっと公視野で見る事にします。

No24056 (774RR さん) に返信
有難うございます。無事コンパイルできました。


シャノンさん有難うございます。



当初の問題自体は解決したのですが、あんどんちんさんが指摘した「T getだと自動で参照型にしてもらえる旨味がなくなっちゃう」が気になります。
重要な事ですし、何よりも面白そうな話題なので、引き続きこの話題で話し会いましょう。
引用返信 編集キー/
■24058 / inTopicNo.10)  Re[6]: 型指定子を認識してくれない
□投稿者/ アキラ (99回)-(2008/08/27(Wed) 12:21:21)
アキラ さんの Web サイト
typename の使いどころについてはここを参照
http://d.hatena.ne.jp/uskz/20080130/p1
引用返信 編集キー/
■24059 / inTopicNo.11)  Re[6]: 型指定子を認識してくれない
□投稿者/ アキラ (101回)-(2008/08/27(Wed) 12:27:24)
アキラ さんの Web サイト
> 当初の問題自体は解決したのですが、あんどんちんさんが指摘した「T getだと自動で参照型にしてもらえる旨味がなくなっちゃう」が気になります。

call_traitsは使ったことないですが

T get()の場合 T が std::string なら std::string get() になってコピーが返って
call_traits を使った場合は最適な型が選ばれるから const std::string& get() になるんじゃないですか。
引用返信 編集キー/
■24060 / inTopicNo.12)  Re[7]: 型指定子を認識してくれない
□投稿者/ 通りすがりのう〜 (1回)-(2008/08/27(Wed) 12:37:16)
わたしも typename の付け忘れはよくやるのですが、
なんども経験しているとエラーメッセージを見てすぐに気付けるようになります。
(よくやるミスってだいたい決まってますから)

この場合、typedef しておけば修正は1箇所で済んだのです。

typedef typename boost::call_traits<T>::param_type param_type;

param_type get() const { return data; } 
void set(param_type d) { data = d; } 

あと、get は const 修飾した方がいいです。

引用返信 編集キー/
■24063 / inTopicNo.13)  Re[7]: 型指定子を認識してくれない
□投稿者/ 774RR (213回)-(2008/08/27(Wed) 12:51:57)
2008/08/27(Wed) 13:05:30 編集(投稿者)
2008/08/27(Wed) 13:05:17 編集(投稿者)

いやもうこれについてはリンク先ですべて述べられ済みだったりするわけで蛇足なのだが。

任意の T について T get() { ... } と書くと、この返却値としてはコピーが生成される。

コピーするコストが高い場合(でかいクラスとか)、ないし、
コピーできない場合(basic_stream はコピーできない)とかには
参照を使って T& get() { ... } であるほうが望ましい場合が多い

参照より安いコストでコピー・使用できる場合(int/double 等の組み込み型)や
そもそも複写が欲しい場合には T get() { ... } のほうが望ましい

call_traits はこの両者を自動で使い分けてくれるというわけで。

使い分けてくれている証明を
std::cout << &hint.get() << std::endl; // error! rvalue のアドレスを取ろうとした
std::cout << &hstr.get() << std::endl; // ok! == &hstr.data

#24060 さん // 番号が違っていたので修正
> あと、get は const 修飾した方がいいです。
だめです。参照を返せなくなります。
get() const と get() の両方を用意するのであればそれなりに意味はあります。

引用返信 編集キー/
■24064 / inTopicNo.14)  Re[8]: 型指定子を認識してくれない
□投稿者/ あんどちん (8回)-(2008/08/27(Wed) 13:06:11)
蛇足ですが、call_traitsのparam_typeはconst修飾されてます。念のため。

引用返信 編集キー/
■24066 / inTopicNo.15)  Re[8]: 型指定子を認識してくれない
□投稿者/ 通りすがりのう〜 (2回)-(2008/08/27(Wed) 13:15:08)
No24063 (774RR さん) に返信
> 2008/08/27(Wed) 13:05:30 編集(投稿者)
> 2008/08/27(Wed) 13:05:17 編集(投稿者)
> 
> いやもうこれについてはリンク先ですべて述べられ済みだったりするわけで蛇足なのだが。
> 
> 任意の T について T get() { ... } と書くと、この返却値としてはコピーが生成される。
> 
> コピーするコストが高い場合(でかいクラスとか)、ないし、
> コピーできない場合(basic_stream はコピーできない)とかには
> 参照を使って T& get() { ... } であるほうが望ましい場合が多い
> 
> 参照より安いコストでコピー・使用できる場合(int/double 等の組み込み型)や
> そもそも複写が欲しい場合には T get() { ... } のほうが望ましい
> 

たしか、『Modern C++ Design』にも載ってましたね。


> #24060 さん // 番号が違っていたので修正
>>あと、get は const 修飾した方がいいです。
> だめです。参照を返せなくなります。
> get() const と get() の両方を用意するのであればそれなりに意味はあります。

あんどちんさんも指摘しておられますが、param_type は const 修飾されているので、
get() const ひとつでいいはずです。

引用返信 編集キー/
■24067 / inTopicNo.16)  Re[9]: 型指定子を認識してくれない
□投稿者/ あんどちん (9回)-(2008/08/27(Wed) 13:28:05)
No24064 (あんどちん さん) に返信
> 蛇足ですが、call_traitsのparam_typeはconst修飾されてます。念のため。

Tが参照型やポインタの場合はそうでもないみたいですね。すいません。
そもそもparam_typeってメソッドのパラメータに用いるためのもので、戻り値で使うような物ではないんじゃないかと思いますが。


引用返信 編集キー/
■24068 / inTopicNo.17)  Re[10]: 型指定子を認識してくれない
□投稿者/ あんどちん (10回)-(2008/08/27(Wed) 13:38:18)
No24067 (あんどちん さん) に返信
> ■No24064 (あんどちん さん) に返信
>>蛇足ですが、call_traitsのparam_typeはconst修飾されてます。念のため。
>
> Tが参照型やポインタの場合はそうでもないみたいですね。すいません。
ここで言ってるのはconst Tのことです。T constの事じゃありません。

> そもそもparam_typeってメソッドのパラメータに用いるためのもので、戻り値で使うような物ではないんじゃないかと思いますが。
>

ここ見るのがいいと思います。
http://www.boost.org/doc/libs/1_36_0/libs/utility/call_traits.htm

# 03での書き込みは辛い
引用返信 編集キー/
■24073 / inTopicNo.18)  Re[9]: 型指定子を認識してくれない
□投稿者/ ネタ好き未記入 (53回)-(2008/08/27(Wed) 14:21:38)
皆さん情報有難うございます。すごく勉強になります。
774RRさんの証明もためしました。
Boost凄いですね。チャンとエラーが出る!
(もしかして普通だったかな?)


>たしか、『Modern C++ Design』にも載ってましたね。

についですが、どこら辺に載っていましたか?
勉強しなおしたいので教えていただけると助かります。
引用返信 編集キー/
■24077 / inTopicNo.19)  Re[10]: 型指定子を認識してくれない
□投稿者/ 通りすがりのう〜 (3回)-(2008/08/27(Wed) 14:43:29)
> そもそもparam_typeってメソッドのパラメータに用いるためのもので、戻り値で使うような物ではないんじゃないかと思いますが。
> ここ見るのがいいと思います。
> http://www.boost.org/doc/libs/1_36_0/libs/utility/call_traits.htm

じつは単純なsetメソッド程度なら void set(const T& d) { data = d; } で十分なのかな?
(T が参照であればそもそも代入できないし、関数内にループがあってその中で引数を使っているわけでもないので)


> >たしか、『Modern C++ Design』にも載ってましたね。
>
> についですが、どこら辺に載っていましたか?
> 勉強しなおしたいので教えていただけると助かります。

何章だったか忘れましたが、たしか前の方の章だったような…
家に帰ったら調べてみます。
引用返信 編集キー/
■24099 / inTopicNo.20)  Re[11]: 型指定子を認識してくれない
 
□投稿者/ 通りすがりのう〜 (4回)-(2008/08/27(Wed) 19:19:23)
>>>たしか、『Modern C++ Design』にも載ってましたね。
>>
>>についですが、どこら辺に載っていましたか?
>>勉強しなおしたいので教えていただけると助かります。
>
> 何章だったか忘れましたが、たしか前の方の章だったような…
> 家に帰ったら調べてみます。

『2.10.3 パラメータ型の最適化』がそうです。
また、5.12 節に使用例があります。

引用返信 編集キー/

次の20件>
トピック内ページ移動 / << 0 | 1 >>

管理者用

- Child Tree -