私のライブラリのconstおよびnon-constテンプレート引数の関数を提供しようとすると、私は奇妙な問題に遭遇しました。以下のソースコード最小例現象である:未定義テンプレート 'class'の暗黙的なインスタンス化
#include <iostream>
template<typename some_type>
struct some_meta_class;
template<>
struct some_meta_class<int>
{
typedef void type;
};
template<typename some_type>
struct return_type
{
typedef typename some_meta_class<some_type>::type test;
typedef void type;
};
template<typename type>
typename return_type<type>::type foo(type & in)
{
std::cout << "non-const" << std::endl;
}
template<typename type>
void foo(type const & in)
{
std::cout << "const" << std::endl;
}
int main()
{
int i;
int const & ciref = i;
foo(ciref);
}
Iは非constバージョンとfooのCONSTバージョンを実装しようとしたが、残念ながら、このコードはCLANG 3.0とgcc 4.6.3でコンパイルされません。
main.cpp:18:22: error: implicit instantiation of undefined template 'some_meta_class'
なんらかの理由で、コンパイラは何らかの理由でconst-referenceにfooの非constバージョンを使用したいとします。 some_meta_classの実装がないため、これは明らかに上記のエラーにつながります。奇妙なことは、あなたが以下の変更のいずれかを実行した場合、コードがうまくコンパイルして動作すること、である:非constバージョン
- コメント解除
この例はもちろん最小限で純粋な学問です。私のライブラリでは、constとnon-constバージョンが異なる型を返すので、この問題に遭遇しました。私はこの問題を部分的に特化したヘルパークラスを使って管理しました。
しかし、なぜ上記の例ではこのような奇妙な動作が起こりますか?なぜコンパイラーは、constバージョンが有効で、より良く一致する非constバージョンを使用したいのですか?
現在、有効な有効なオーバーロードのリストを生成する段階にあり、return_typeを正しくインスタンス化できないため、そこに救済が行われます(return_typeのtypedefをコメントアウトしてください) –
PlasmaHH