template constructor vs copy-constructor part2

  • 以下のコードはtest1でassertion failedとなる
  • test2では、(3)がB型にキャストすることによって(1)を優先するようにしているのでassertion failedにならない
  • 何が問題かと言うと、VC++は、このstatic_castの抜け落ちたかのように動作するcopy-constructorを生成することがあるらしい (そのときはtest1と同様に(2)が呼ばれる)
    • これはたぶんVC++のバグだと思う (12.8/8)
    • このために、boost::base_from_memberでCopyableなクラスを作ることはできない
  • 以上の話はoperator=でも全く同様
  • そこで、disable_ifを使って、part1もまとめて対策しよう (ソースコード)
    • これより分かりやすいのは、(3)のようにコンパイラの代わりに自分で書くこと

[]#include[] []<cassert>[]

[]struct[] []B[]
[]{[]
[]B[][]() { }[]

[]// implicitly-declared copy-constructor[]
[]// B(B const&); // (1)[]

[]template[][]< [][]class[] []T[][] >[]
[]B[][]([][]T[] []const[][]& [][]x[][]) [][]// (2)[]
[] {[]
[]assert[][]([][]false[][]);[]
[] }[]

[]};[]

[]struct[] []D[][] : [][]B[]
[]{[]
[]D[][]() { }[]

[]D[][]([][]D[] []const[][]& [][]other[][]) : [][]// (3)[]
[]B[][]([][]static_cast[][]<[][]B[] []const[][]&>([][]other[][]))[]
[] { }[]
[]};[]


[]void[] []test1[][]()[]
[]{[]
[]D[] []d[][];[]
[]B[] []b[][]([][]d[][]); [][]// assertion failed[]
[]}[]


[]void[] []test2[][]()[]
[]{[]
[]D[] []d1[][];[]
[]D[] []d2[][]([][]d1[][]); [][]// OK[]
[]}[]