2010-01-28

C++0xの機能ふたつ

auto({1}).size()で行けない?

autoは、5.2.3 Explicit type conversion (functional notation) [expr.type.conv]には使えない。たしかに、Explicit type conversionの方には、simple-type-specifierが使えると書いてある。ただし、7.1.6.4 p3 auto specifier [dcl.spec.auto]に、以下のように書いてある。

This use of auto is allowed when declaring objects in a block (6.3), in namespace scope (3.3.6), and in a for-init-statement (6.5.3).

というわけで、以下のようなコードは書けない。

// ill-formed
auto x = auto(0) ;

decltypeには、このような制限は見当たらなかったので、以下のように書けるはずだ。

// well-formed?
auto x = decltype(0)(0) ;

が、VC10ではエラーがでる。さて、どうなのか。どこかに規格の見落としがあるのだろうか。さらに調べなければ。

これなら通った。

auto x = (decltype(0))(0) ;

優先順位の問題なのか?

#include <cstdio>

template <class t_any>
void check(const t_any &val)
{
std::puts("this is const left value.");
}

template <class t_any>
void check(t_any &&val)
{
std::puts("this is right value.");
}

int main(void)
{
check(100);

int x = 200;

check(x);

return 0;
}

GCC4.4.1で両方右辺値になるんだけどなんで?

おそらく、GCCのバグである。Overload Resolutionは、Argument Deductionの後に行われる。そして、テンプレート引数のrvalue referenceに対しては、lvalue referenceもdeduceされる。その場合、&&は、単に無視される。

さて、argument Deductionの後の関数は、どちらも同じ程度にマッチする「候補」である。すると、このコードは、どちらのオーバーロード関数を呼び出せばいいのか、曖昧である。したがって、コンパイルエラーになるべきである。

ちなみに、lvalueは、left-hand-valueの略ではないし、rvalueはright hand valueではない。いまだに古臭いC言語の世界に生きているのなら、使ってもいい。

No comments: