6

g++ 4.9 および clang 3.4 でテストすると、このコードがコンパイルされないのはなぜですか。

namespace {

template<typename T>
constexpr auto f(T && t) noexcept {
    return true;
}

template<typename T, typename... Ts>
constexpr auto f(T && t, Ts && ... ts) noexcept(noexcept(f(ts...))) {
    return f(ts...);
}

}   // namespace

int main() {
    f(true, 0, 5u);
}

しかし、このコードは次のことを行います。

namespace {

template<typename T>
constexpr auto f(T && t) noexcept {
    return true;
}

template<typename T>
constexpr auto f_helper(T && t) noexcept(noexcept(f(t))) {
    return f(t);
}

template<typename T, typename... Ts>
constexpr auto f_helper(T && t, Ts && ... ts) noexcept(noexcept(f(ts...))) {
    return f(ts...);
}

template<typename T, typename... Ts>
constexpr auto f(T && t, Ts && ... ts) noexcept(noexcept(f_helper(ts...))) {
    return f(ts...);
}

}   // namespace

int main() {
    f(true, 0, 5u);
}

f_helper 関数を定義する必要はありません。その場合、decltype によって指定された正しい戻り値の型が必要です。

最初のコードも 1 つまたは 2 つの引数に対してコンパイルされますが、3 つ以上の引数で呼び出そうとすると、呼び出す関数が一致しないというエラーが発生します。最初のコードの clang エラーは次のとおりです。

source/main.cpp:9:59: error: call to function 'f' that is neither visible in the template definition nor
      found by argument-dependent lookup
        constexpr auto f(T && t, Ts && ... ts) noexcept(noexcept(f(ts...))) {
                                                                 ^
source/main.cpp:9:17: note: in instantiation of exception specification for 'f<bool, int, unsigned int>'
      requested here
        constexpr auto f(T && t, Ts && ... ts) noexcept(noexcept(f(ts...))) {
                       ^
source/main.cpp:16:3: note: in instantiation of function template specialization '<anonymous
      namespace>::f<bool, int, unsigned int>' requested here
                f(true, 0, 5u);
                ^
source/main.cpp:9:17: note: 'f' should be declared prior to the call site
        constexpr auto f(T && t, Ts && ... ts) noexcept(noexcept(f(ts...))) {
                       ^
1 error generated.
4

1 に答える 1

5

3.3.2/1名前の宣言のポイントは、完全な宣言子 (第 8 節) の直後で、初期化子 (存在する場合) の前です...

exception-specificationは構文的に宣言子の一部です。したがって、関数名は、それ自体の例外仕様内のスコープにはありません。

于 2014-05-21T02:22:05.563 に答える