class模板推导指南中是否可以使用折叠表达式?
Is it possible to use fold expression in class template deduction guide?
我做了一个简单的测试如下:
#include <iostream>
template <typename T, std::size_t N, std::size_t D> struct MyArray {
template <typename First, typename ... Rest> MyArray(First, Rest...);
int dimension[N];
T m_array[D];
};
template <typename First, typename... Rest> MyArray(First first, Rest... values)
-> MyArray<First, 1 + sizeof...(values), (values * ...)>;
int main()
{
MyArray arr{3, 2, 3};
return 0;
}
编译器抱怨它:
main.cpp:14:13: No viable constructor or deduction guide for deduction of template arguments of 'MyArray'
main.cpp:4:50: candidate template ignored: couldn't infer template argument 'T'
main.cpp:9:45: candidate template ignored: substitution failure [with First = int, Rest = <int, int>]: non-type template argument is not a constant expression
main.cpp:3:60: candidate function template not viable: requires 1 argument, but 3 were provided
如果我将 (values * ...)
替换为 18,则一切正常。
有什么方法可以从 C++ 中的演绎指南中的折叠表达式中获益吗?
您不能在常量表达式中使用函数参数的值,尤其是在模板参数中。
如果你想为不同的值推导不同的类型,你需要确保类型也因值而异。
示例:
#include<type_traits>
template<auto V>
constexpr auto constant = std::integral_constant<decltype(V), V>{};
//...
MyArray arr{3, constant<2>, constant<3>};
据我所知,这应该与您的推导指南一起工作,尽管 GCC 和 MSVC 似乎都对这段代码有问题,这对我来说看起来像是错误。
std::integral_constant
可以隐式转换为其模板参数中的值。此转换不需要访问该类型的给定瞬间的值,因此 (values * ...)
应该没问题。
sizeof...(values)
总是没问题,因为它根本不访问 values
。它只是扩展到包中的项目数。
GCC 声称 (values * ...)
不包含未展开的包,这对我来说似乎是错误的。 MSVC 有一个内部编译器错误,这绝对是一个错误。但是 Clang 接受这种变化。
我做了一个简单的测试如下:
#include <iostream>
template <typename T, std::size_t N, std::size_t D> struct MyArray {
template <typename First, typename ... Rest> MyArray(First, Rest...);
int dimension[N];
T m_array[D];
};
template <typename First, typename... Rest> MyArray(First first, Rest... values)
-> MyArray<First, 1 + sizeof...(values), (values * ...)>;
int main()
{
MyArray arr{3, 2, 3};
return 0;
}
编译器抱怨它:
main.cpp:14:13: No viable constructor or deduction guide for deduction of template arguments of 'MyArray'
main.cpp:4:50: candidate template ignored: couldn't infer template argument 'T'
main.cpp:9:45: candidate template ignored: substitution failure [with First = int, Rest = <int, int>]: non-type template argument is not a constant expression
main.cpp:3:60: candidate function template not viable: requires 1 argument, but 3 were provided
如果我将 (values * ...)
替换为 18,则一切正常。
有什么方法可以从 C++ 中的演绎指南中的折叠表达式中获益吗?
您不能在常量表达式中使用函数参数的值,尤其是在模板参数中。
如果你想为不同的值推导不同的类型,你需要确保类型也因值而异。
示例:
#include<type_traits>
template<auto V>
constexpr auto constant = std::integral_constant<decltype(V), V>{};
//...
MyArray arr{3, constant<2>, constant<3>};
据我所知,这应该与您的推导指南一起工作,尽管 GCC 和 MSVC 似乎都对这段代码有问题,这对我来说看起来像是错误。
std::integral_constant
可以隐式转换为其模板参数中的值。此转换不需要访问该类型的给定瞬间的值,因此 (values * ...)
应该没问题。
sizeof...(values)
总是没问题,因为它根本不访问 values
。它只是扩展到包中的项目数。
GCC 声称 (values * ...)
不包含未展开的包,这对我来说似乎是错误的。 MSVC 有一个内部编译器错误,这绝对是一个错误。但是 Clang 接受这种变化。