使用 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.