const int 再び

  • const intを使うと、ODR違反が起きてしまう場合がある
    • その条件が不明確のようだ・・・参照
    • 標準にはアドレスが使用されないなら大丈夫と書いてある(3.2.5)
  • boost::mpl::integral_cはODR違反の起きる前にそもそも定義がない・・・参照
  • というわけで、定義が必要なときにはODR違反しないように提供するstatic_c

[]#include[] []<boost/mpl/integral_c.hpp>[]

[]#define[][] MACRO_THREE 3[]


[]int[] []const[] []const_three[][] = [][]3[][];[]


[]struct[] []mpl_three[][] :[]
[]boost[][]::[][]mpl[][]::[][]integral_c[][]<[][]int[][], [][]3[][]>[]
[]{ };[]


[]template[][]< [][]class[] []T[][], [][]T[] []v[][] >[]
[]struct[] []static_c[]
[]{[]
[]static[] []T[] []const[] []value[][] = [][]v[][];[]
[]};[]

[]template[][]< [][]class[] []T[][], [][]T[] []v[][] >[]
[]T[] []const[]
[]static_c[][]<[][]T[][], [][]v[][]>::[][]value[][];[]


[]struct[] []three[][] :[]
[]static_c[][]<[][]int[][], [][]3[][]>[]
[]{ };[]


[]inline[]
[]void[] []foo[][]([][]int[] []const[][]& [][]x[][])[]
[]{[]
[]BOOST_CHECK[][]( [][]x[][] == [][]3[][] );[]
[]}[]


[]template[][]< [][]class[] []T[][] >[]
[]void[] []bar[][]()[]
[]{[]
[] ::[][]foo[][]([][]MACRO_THREE[][]); [][]// ok[]
[] ::[][]foo[][]([][]const_three[][]); [][]// possible ODR violation[]
[] ::[][]foo[][]([][]mpl_three[][]::[][]value[][]); [][]// link error[]
[] ::[][]foo[][]([][]three[][]::[][]value[][]); [][]// ok[]
[]}[]