人生初心者の雑記

すべてにおいてド素人な人がいろんなことを書くよ

sfinaeのenabler 2/2

じゃあenablerについてのど素人丸出し糞的外れな疑問をかくよー。

/////////////////////////////////コード始まり
extern void * enabler ;
template < typename T,
typename std::enable_if<std::is_arithmetic<T>::value >::type *&  = enabler >
void f(T)
{
std::cout << "T is arithmetic" << std::endl;
}

////////////////////////////コード終わり

sfinaeについての例を探すとこんなのが出てくる(このコードは巷で有名な江添さんのサイト

本の虫: C++0xにおけるenable_ifの新しい使い方

から持ってきました)

 

「なんでenablerで初期化してリンカエラーにならないの?」

 

だって,たとえTがarithmeticで、eneble_if::typeがvoidだとして、void*& を enablerデフォルト実引数初期化するときに,enablerの定義がいるはずじゃん(それがそもそも違うのかもしれんけど)

 

というわけでこんな風に変更してみた

std::enable_if<std::is_arithmetic<T>::value >::type *  = static_cast<void*>(&enabler )>

参照を外してenablerのアドレスを渡すようにしました

vc++では通った。ideoneでは駄目だった。こんなこと言われた

prog.cpp:13:87: error: could not convert template argument ‘(void*)(& enabler)’ to ‘std::enable_if<true, void>::type* {aka void*}’

わけわかんない

つぎに、enable_ifの部分は最初に書いたとおりに戻して、main関数にこれ入れてみた


    f<int, enabler>(arithmetic);

vc++もideoneも通った。(しかしvc++のいんてりせんすは    1    IntelliSense: オーバーロードされた関数 "f" のインスタンスが引数リストと一致しません
            引数の型: (int)    とか言ってくる。コンパイル通って実行できるけど)

ちょっと外れて、main関数にこういうのを入れてみる

void* foo = &enabler

vc++通らない。未解決だそうだ。ideone通る。へー。

 

 

とまぁこんな風に、externがらみの奴がすっごいわかんない。

規格をよんでも、リンカについての詳しい話が見つかんないし、externalな変数が参照できる条件も見つからん。俺が見落としてるのか、実装依存なのか。

 

そうはいっても、テンプレートのデフォルト実引数にenablerを使うってのはboostライブラリに採用されているらしい。つまり合法であるという根拠があるはずなの。

あー見つかんないわかんない。