boost::tupleとForeachとtemplate

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
chibago

boost::tupleとForeachとtemplate

#1

投稿記事 by chibago » 12年前

お世話になっております。chibagoです。
おそらく、開発環境側のバグだとは思いますが、納得のいかないエラー
が発生し何とかしたいと思っております。もし、同様の経験をされた方で
解決策をご存知のかたはご教授いただければと思います。

環境はlinux gcc4.6 boost 1.46です。

以下の様に、問題を抽出したコード(挙動に関してはまったく意味がございません。)
を示します。

コード:

#include <map>
#include <list>
#include <boost/tuple/tuple.hpp>
#include <boost/tuple/tuple_io.hpp>
#include <boost/foreach.hpp>
#include <vector>
#include <iostream>

template <typename T>
void typedef_test1(){
  typedef std::map<int, std::list<boost::tuple<T> > > data_map;
  typedef std::pair<int, std::list<boost::tuple<T> > > data_pair;
  typedef boost::tuple<T> data;
  data_map test_map;
  BOOST_FOREACH(const data_pair &pair, test_map){
  BOOST_FOREACH(const data &val, pair.second){
    std::cout<<val.get<0>()<<std::endl;   
 }} 
 }


template <typename T>
void typedef_test2(){
  typedef std::map<int, std::list<boost::tuple<T> > > data_map;
  typedef std::pair<int, std::list<boost::tuple<T> > > data_pair;
  typedef boost::tuple<double> data;
  data_map test_map;
  BOOST_FOREACH(const data_pair &pair, test_map){
  BOOST_FOREACH(const data &val, pair.second){
    std::cout<<val.get<0>()<<std::endl;   
 }} 

}

template <typename T>
void typedef_test3(){
  typedef std::map<int, std::list<boost::tuple<T> > > data_map;
  typedef std::pair<int, std::list<boost::tuple<T> > > data_pair;
  typedef boost::tuple<T> data;
  data_map test_map;
  BOOST_FOREACH(const data_pair &pair, test_map){
  BOOST_FOREACH(const data &val, pair.second){
 }} 
}

int main(){
  typedef_test1<double>();
}

このtypedef_test1関数をコンパイル(このときは、typedef_test2,typedef_test3はコメントアウトします)
すると以下のようなエラーが発生します。

test.cpp: 関数 ‘void typedef_test1()’ 内:
test.cpp:17:27: エラー: expected primary-expression before ‘)’ token
test.cpp: 関数 ‘void typedef_test1() [with T = double]’ 内:
test.cpp:48:25: instantiated from here
test.cpp:17:5: エラー: ‘operator<<’ で ‘std::cout << val.boost::tuples::cons<HT, boost::tuples::null_type>::get [with int N = N, HT = double, typename boost::tuples::access_traits<typename boost::tuples::element<N, boost::tuples::cons<HT, boost::tuples::null_type> >::type>::const_type = <型エラー>]’ 内にあるものが適合しません

typedef_test2,typedef_test3はこれの修正版で、typedef dataの際にtemplateパラメータを使わずに
直接doubleとしたものとtemplateパラメータはそのままでtupleのデータ取り出し関数を呼ばない
ために処理そのものを削除したものです。これらは問題なくとおります。

結論としては、templateとboost_foreachを並用したときにtupleの操作関数getを使用すると
異常が発生する(templateパラメータTが解読できないのでしょうか)と言うことだと思います。

コーディングで不適切なところ、もしくは解決策がありましたら
ご指導いただければ幸です。

アバター
a5ua
記事: 199
登録日時: 13年前

Re: boost::tupleとForeachとtemplate

#2

投稿記事 by a5ua » 12年前

コード:

template <typename T>
void typedef_test1(){
	typedef std::map<int, std::list<boost::tuple<T> > > data_map;
	typedef std::pair<int, std::list<boost::tuple<T> > > data_pair;
	typedef boost::tuple<T> data;
	data_map test_map;
	BOOST_FOREACH(const data_pair &pair, test_map){
		BOOST_FOREACH(const data &val, pair.second){
			std::cout<<boost::get<0>(val)<<std::endl;   
		}
	} 
}
もしくは、

コード:

template <typename T>
void typedef_test1(){
	typedef std::map<int, std::list<boost::tuple<T> > > data_map;
	typedef std::pair<int, std::list<boost::tuple<T> > > data_pair;
	typedef boost::tuple<T> data;
	data_map test_map;
	BOOST_FOREACH(const data_pair &pair, test_map){
		BOOST_FOREACH(const data &val, pair.second){
			std::cout<<val.template get<0>()<<std::endl;   
		}
	} 
}
としたら、ideone上では通りました。(gcc-4.3.4)

メンバ関数のgetを使う場合は、val.getがテンプレートであることを明示してあげないと、
“(std::cout << val.get) < 0 > (() << std::endl)”と解釈されてしまうのが原因のようです。
                   ^エラー:式がない!

chibago

Re: boost::tupleとForeachとtemplate

#3

投稿記事 by chibago » 12年前

a5uaさん
ありがとうございました。

さっそくためしてみたところ、
こちらの環境においても動作が確認できました。

一部分だけテンプレートが崩れたソースとなっておりましたので、
助かりました。

しかし、tupleに対するtamplateの指定は不思議な形をしていますね。

chibago

Re: boost::tupleとForeachとtemplate

#4

投稿記事 by chibago » 12年前

解決のチェックを忘れていました。

閉鎖

“C言語何でも質問掲示板” へ戻る