template <class A>
class B;
template <class A>
class B<const A>{};
template <class A, int N>
class B<A[N]>{};
template <class A>
class B<A*>{};
template <class A>
class B<A&>{};
次のテンプレートのインスタンス化が正常に動作考慮する:
A<int*&>
A<const int*>
A<int*[3]>
が、以下のいずれかが動作しません:
A<const int[3]>
を
この特定の組み合わせが無効である理由はありますか、おそらくg ++ 4.6のバグでしょうか.3?
私はSFINAEとboost :: disable_if <を使用してこの問題を回避することができましたが、少なくとも問題は解決されています。私は問題のエラーがあいまいなクラステンプレートのインスタンス化であり、それは、配列のためのconstのための過負荷や過負荷の間で決めることができなかったことを言及するのを忘れてしまった
EDIT
。
EDIT2
これは、ポインタとは何の関係もありません、ここで完全なコンテキストだ:
私は本C++テンプレートメタプログラミングを通じてつもりだと質問2-3(第2章をしています質問3):
type_descriptorクラステンプレートを実装するには、type_descriptorクラステンプレートを使用します。このテンプレートは、ストリーミングされたときにテンプレートパラメータのタイプを出力します。 注:使用できませんRTTIは、標準の18.5.1 [lib.type.info]パラグラフ7によると、意味のある結果を返すことは保証されていないので、同じ効果があります。
//QUESTION 2-3
template <class T, class enable = void>
struct type_descriptor
{
std::string operator()() const
{
return "Unknown";
}
};
//specializations for primitive types
#define TYPE_DESC_SPEC(type) template <> \
struct type_descriptor<type,void> \
{std::string operator()() const{return #type;}};
TYPE_DESC_SPEC(int)
TYPE_DESC_SPEC(long)
TYPE_DESC_SPEC(void)
TYPE_DESC_SPEC(short)
TYPE_DESC_SPEC(unsigned char)
TYPE_DESC_SPEC(unsigned short)
TYPE_DESC_SPEC(unsigned long)
//specializations for modifiers *, const, &, and [N]
template <class T>
struct type_descriptor<T&,void>
{std::string operator()(){return type_descriptor<T>()() + " &";}};
template <class T>
struct type_descriptor<T*,void>
{std::string operator()(){return type_descriptor<T>()() + " *";}};
//Replace void with what's in the comment for the workaround.
template <class T>
struct type_descriptor<const T, void/*typename boost::disable_if<boost::is_array<T> >::type*/>
{std::string operator()(){return type_descriptor<T>()() + " const";}};
template <class T>
struct type_descriptor<T(*)(),void>
{std::string operator()(){return type_descriptor<T>()() + " (*)()";}};
template <class T, class U>
struct type_descriptor<T(*)(U),void>
{std::string operator()(){return type_descriptor<T>()() + " (*)(" + type_descriptor<U>()() + ")";}};
template <class T, int N>
struct type_descriptor<T[N],void>
{
std::string operator()()
{
std::stringstream s;
s << type_descriptor<T>()() << " [" << N << "]";
return s.str();
}
};
template <class T>
struct type_descriptor<T[],void>
{std::string operator()(){return type_descriptor<T>()() + " []";}};
//Now overload operator<< to allow streaming of this class directly
template <class T>
std::ostream & operator<<(std::ostream & s, type_descriptor<T> t)
{
return s << t();
}
//END QUESTION 2-3
使用例がある:回避策である場合(
std::cout << "\nQuestion 2-3 results\n";
std::cout << type_descriptor<int*>() << std::endl;
std::cout << type_descriptor<int*[3]>() << std::endl;
std::cout << type_descriptor<std::string*>() << std::endl;
std::cout << type_descriptor<const int&>() << std::endl;
std::cout << type_descriptor<const int *const&>() << std::endl;
std::cout << type_descriptor<int[4]>() << std::endl;
std::cout << type_descriptor<int(*)()>() << std::endl;
std::cout << type_descriptor<int*&(*)(const char &)>() << std::endl;
std::cout << type_descriptor<int*&>() << std::endl;
std::cout << type_descriptor<int[]>() << std::endl;
std::cout << type_descriptor<const long[]>() << std::endl;
、対応する出力は、次のように(コンパイルエラーを回避を含む)
マイ溶液でありますそれ以外の場合は最後のコンパイルではコンパイルされません)。
int * int * [3] Unknown * int const & int const * const & int [4] int (*)() int * & (*)(Unknown const &) int * & int [] long const []
C++は異なることがありますテンプレートパラメータのポインタと配列は、複素数型を正しく、再帰的に分離して、const A[]
以外の正しい結果を出力することができます。それは助けが必要です
これで推測するつもりですが、 'const int [3]'が 'const int *'に崩壊すると思います。 –
@AdrianCornishそれはそうではありません。編集を参照してください。それ以外にも、3番目の有効な例があれば、どちらもうまくいかないはずです。 – SirGuy
'const int *'が 'int *'と異なっているため、3番目のコードは機能します.- –