いくつかの宣言が与えられた:
template <class T, T t>
struct foo {};
template <class T>
constexpr T ident(T t) {
return t;
}
constexpr int bar() {
return 0;
}
int main(int argc, const char *argv[])
{
foo<bool, true> a;
foo<int, bar()> b;
foo<int, ident(0)> c;
foo<int (*)(), bar> d;
foo<int(*)(), ident(&bar)> e; // not accepted (gcc 4.7.2 crashes here, even)
return 0;
}
余談ですが、興味深いことに、これによりgcc4.7.2でセグメンテーション違反が発生しました。エラーメッセージ(「外部リンケージを持つ関数のアドレスである必要があります」)を取得するために、4.8.0スナップショットのsvnビルドを実行する必要がありました...
最初はOKで、最後は許可されないのはなぜですか?このconstexprはcases広告のようなものではありませんか?コンパイラーは、他のタイプに対してそれを行うことができるので、どの関数ident(&bar)
が話しているのかを完全に決定できるようです。