使用SFINAE検出するポッドらしさのタイプのC++
-
22-08-2019 - |
質問
のオリジナルタイトルは 回避策のためのSFINAEバグVS2005C++
これは暫定利用SFINAEに相当のis_podテンプレートクラスに存在するTR1(VS2005ありませんTR1ます。持っていることがあり、その 値 会員の場合はtrueでテンプレートパラメータがポッドタイプを含むプリミティブ型は、構造体の製し、falseの場合ではない非自明なコンストラクタ).
template <typename T> class is_pod
{
public:
typedef char Yes;
typedef struct {char a[2];} No;
template <typename C> static Yes test(int)
{
union {T validPodType;} u;
}
template <typename C> static No test(...)
{
}
enum {value = (sizeof(test<T>(0)) == sizeof(Yes))};
};
class NonPOD
{
public:
NonPod(const NonPod &);
virtual ~NonPOD();
};
int main()
{
bool a = is_pod<char>::value;
bool b = is_pod<NonPOD>::value;
if (a)
printf("char is POD\n");
if (b)
printf("NonPOD is POD ?!?!?\n");
return 0;
}
問題は、VS2005いTR1んに連合(あるべきでない場合に有効となり、テンプレートパラメータではないポッド)aもbを評価します。
の回答を掲載します。読みにくいのコード)を実現しまうようと努力している、といった間違いです。このアイデアをSFINAE行動と適応のテンプレート must_be_pod (この書 不完全なC++, が可能であり、これまでのようにも見られ別の場所があります。実は、このえる必要があるか特定のルールSFINAEなどの規格はもちろんのこと、.このバグに対すよね。
解決
最大の問題とアプローチできないSFINAEこSFINAEにのみ適用されるパラメータ型、および戻り値の型です。
しかし、すべてのSFINAEの状況基準、適用されます。その
- 配列のボイドを参考に、機能、または無効サイズ
- タイプ一員とな
- ポインタ参照への参照の参照だけでなく、ボイド
- ポイントの非クラスタイプ
- 無効な変換のテンプレートパラメータの値
- 機能と引数の型がvoid
- const/揮発性機能タイプ
ことになるだろうなぜブースト文書、ある:
いくつかのしい無指定の)伝 からのコンパイラ、ispodません 報告に対するクラスまたは構造体である POD;これは常に安全である場合 サブ最適です。現在(2005年) MWCW9Visual C++8の 必要なコンパイラ-_intrinsics.
他のヒント
このどちらかVS2008では動作しませんが、私はあなたがあまりにもことを知っていた疑いがあります。 SFINAEは、テンプレートパラメータのテンプレート引数を推定するためにあります。あなたは本当にあなたが別のタイプ(すなわち、労働組合が非PODを使用することはできません)と互換性のないタイプを作成することができるにもかかわらず、タイプのコンストラクタネスを明らかに何かの種類を推測することはできません。
実際には、VS 2008はstd::tr1::type_traits
を実装するための形質のコンパイラのサポートを使用します。
is_pod<T>::test(...)
がis_pod<T>::test(0)
あまりにも一致しますので、私は、あなたがここにSFINAEをしようとしている方法についてはよく分かりません。
:あなたの代わりに「int型の異なるタイプを使用する場合はおそらく、あなたはより良い試合を取得したいですtemplate <typename T> class is_pod
{
struct my_special_type { };
public:
typedef char Yes;
typedef struct {char a[2];} No;
template <typename C> static Yes test(my_special_type)
{
union {T validPodType;} u;
}
template <typename C> static No test(...)
{
}
enum {value = (sizeof(test<T>(my_special_type())) == sizeof(Yes))};
};
また、 Boost.Enable_i <で見たいと思うかもしれません/> FあなたのためにSFINAEを行うには - あなたはあなた自身のライブラリを実装したり、何らかの理由でしようとしている場合を除き、
。