今まで user-defined literals では名前空間を使えないと思い込んでいましたが,
規格を読むと,名前検索は普通の関数と同様に行われるようなので,普通に
名前空間内で定義し,その名前空間内で特に何も考えずに使用することも可能だし,
違う名前空間であっても, using
宣言を使うことで普通に呼び出せるようです.
具体例を挙げると,
#include <complex> #include <type_traits> #define STATIC_ASSERT(...) static_assert( __VA_ARGS__, #__VA_ARGS__ ) // 虚数単位は j inline constexpr std::complex<double> operator "" _j( long double imag ) { return std::complex<double>( 0, static_cast<double>(imag) ); } namespace ns { // 名前空間内で定義された 別の _j (区別のため float を使う) inline constexpr std::complex<float> operator "" _j( long double imag ) { return std::complex<float>( 0, static_cast<float>(imag) ); } void f() { constexpr auto z = 1_j; // グローバルに operator "" _j はあるが, ns::operator "" _j が呼ばれる STATIC_ASSERT( std::is_same< decltype(z), std::complex<float> const >::value ); } } namespace ns2 { void g() { // using 宣言で使う user-defined literals を指定 using ns::operator "" _j; // グローバルの operator "" ではなく ns::operator "" _j が呼ばれる constexpr auto z = 1_j; // …筈なのだが上手くいかない. gcc のバグ? // STATIC_ASSERT( std::is_same< decltype(z), std::complex<float> const >::value ); } } int main() { ns::f(); ns2::g(); constexpr auto z = 1_j; // グローバルの operator "" _j が呼ばれる STATIC_ASSERT( std::is_same< decltype(z), std::complex<double> const >::value ); }
上記のコードを最新の GCC4.7 (gcc-4.7-20111029)でコンパイルさせると,問題なくコンパイル通ります.
なので,やっぱ user-defined literals さんは滅びなくて正解だった…のかなぁ? うーん.