Rum*_*rak 4 c++ recursion decltype c++11 return-type-deduction
在处理C++ 11类型集时,我尝试实现此功能(剥离到最小):
constexpr auto test() -> bool;
template <typename T, typename... Rest>
constexpr auto test() -> decltype(test<Rest...>())
{
return {};
}
Run Code Online (Sandbox Code Playgroud)
gcc和clang都对此感到窒息.Clang说:
test.cpp:54:40: error: 'Rest' does not refer to a value
constexpr auto test() -> decltype(test<Rest...>())
^
Run Code Online (Sandbox Code Playgroud)
gcc抱怨:
test.cpp:54:44: error: expected primary-expression before ‘...’ token
constexpr auto test() -> decltype(test<Rest...>())
Run Code Online (Sandbox Code Playgroud)
我想这是因为在decltype查看它时,甚至没有完全声明测试的可变版本.
但是,当我在C++ 14中使用返回类型推导时,这编译得很好:
constexpr auto test() -> bool;
template <typename T, typename... Rest>
constexpr auto test()
{
return test<Rest...>();
}
Run Code Online (Sandbox Code Playgroud)
似乎test在这里被认为是充分宣布的.
我想知道为什么这对decltype变体不起作用?即使我打开C++ 14支持?
PS:事实证明,我甚至无法调用C++ 14函数,所以也许整个事情都很糟糕......
一个问题是您的第一个test重载不是函数模板,因此无法使用test<>()语法调用.
但是,decltype这并不适用于递归的可变参数函数,因为返回类型是函数声明的一部分,因此在查找名称时不会声明重载.
您可以使用模板类在C++ 11中解决此问题:
template <typename... Ts>
struct test;
template <typename T, typename... Ts>
struct test<T,Ts...> {
static decltype(test<Ts...>::value()) value() { return test<Ts...>::value(); }
};
template <>
struct test<> {
static bool value() { return true; }
};
Run Code Online (Sandbox Code Playgroud)
在C++ 14中,您可以使第一个重载采用单个模板参数,第二个采用两个参数包:
template <typename T>
constexpr auto test() -> bool { return true; }
template <typename T, typename U, typename... Rest>
constexpr auto test()
{
return test<U,Rest...>();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
406 次 |
| 最近记录: |