鍋あり谷あり

テーマを決めずに適当に書いています。

インスパイヤとインスパイア

のまねこ騒動のせいで、インスパイヤに変な意味が加わってしまった。
のはまあいいとしても。
意味が逆転しているのが興味深い。
もとの意味では

彼は、シェイクスピアの作品にインスパイアされ、あの映画を作ったといわれている

というように使う。能動態にすると:

シェイクスピアの作品が彼をインスパイアして、あの映画ができたといわれている

となる。つまり、AがBをインスパイアした場合、情報はAからBに流れている。

しかし、最近流通し始めた用法では
id:debedebe:20051105
のように、AがBをインスパイヤした場合、情報がBからAに流れている。

念のために書いておくと、AVEX の人が書いた文章は「アスキーアートインスパイヤされて」となっているので、情報の流れる方向という観点からは、本来の用法と同じである。

インスパイアが盗作と関連づけられるような意味になること自体はそれほど困らないように思うが、情報の流れが逆になっているので、非常に意味をとりづらくなっている。

先の例では一方がシェイクスピアなので誤解が生じにくいが「この小説は彼の漫画にインスパイヤされたんです」「彼の漫画は、こないだの直木賞をインスパイアしたみたいです」とか言うと、何がどうなのかさっぱりわからない。

#こういう例が他にあるかどうかと考えてみたんだが、思い当たらなかった。

型から推論する

boost::tuple を直接利用しなくてもいいのであれば、
id:mb2sync:20051108:p1
でやっているようなことは、もうちょっと直接的に書くこともできる。
要点だけを書くと:

template< typename t > struct xtuple_base
{
  t m;
  xtuple_base( const t & _m ) : m( _m ){}
  t & get(){  return m;  }
};

template< typename t0, typename t1 > struct xtuple
  : public xtuple_base< t0 >
  , public xtuple_base< t1 >
{
	xtuple( const t0 & _m0, const t1 & _m1 )
	: xtuple_base< t0 >( _m0 )
	, xtuple_base< t1 >( _m1 )
	{}
	xtuple( const t1 & _m1, const t0 & _m0 )
	: xtuple_base< t0 >( _m0 )
	, xtuple_base< t1 >( _m1 )
	{}
	template< typename t >
	t & get(){  return xtuple_base< t >::get(); }
};

void test()
{
	xtuple< int, double > foo( 1, 2.0 );
	xtuple< float, char > bar( 'c', 3.0f ); // テンプレート引数の順序とコンストラクタの引数の順序が違うが、OK。
	xtuple< int, int > baz( 1, 1 ); // コンパイルエラー
	cout << foo.get<int>() << ", " << foo.get<double>() << endl; // -> 1, 2
	cout << bar.get<char>() << ", " << bar.get<float>() << endl; // -> c, 3
}

こんな感じ。
デフォルトコンストラクタとか、コピーコンストラクタとか、const 版の get とか、まだまだ書かなくてはいけないものはたくさんあるけれど。

コンストラクタを2個書いたのは、test() 内で使われているとおり、引数の順序を憶えなくてもよくするため。

上記はテンプレート引数2個のバージョンなのでコンストラクタが2個で済んでいるが、テンプレート引数が増えると、必要なコンストラクタの数が指数関数的に増えてしまう。
テンプレート引数5個なら、コンストラクタが120個になる。うへ。

でも十分便利そうな気がする。どうだろう。