无法累积编译时间常量
Failing to accumulate compile time constants
我正在尝试创建可变 int
参数向量并对其执行 +
运算符。
例如:
vec<1,2,3> v1;
vec<4,5> v2;
auto res = v1+v2;
res.print(); // should print 5 7 3 vec<5,7,3> is the result.
现在我想创建结构 vecSum
,它将对提供给它的向量求和;
namespace ex {
template<int... N>
struct vec
{
static const int size = sizeof...(N);
void print() {
((std::cout << N << " "), ...);
}
};
template<int...N, int...M, int ...S>
auto add(vec<N...>, vec<M...>, std::index_sequence<S...>) {
constexpr int arr1[sizeof...(S)]{ N... };
constexpr int arr2[sizeof...(S)]{ M... };
return vec<(arr1[S] + arr2[S])...>{};
}
template<int...N, int...M>
auto operator+(vec<N...> v1, vec<M...> v2) {
constexpr size_t size = std::max(sizeof...(N), sizeof...(M));
return add(v1, v2, std::make_index_sequence<size>{});
}
template<typename... Args>
auto all(Args... args) { return (... + args); }
template<typename... Ts>
struct vecSum
{
static constexpr auto res = all(Ts);
};
}
这个测试工作正常:
ex::vec<1, 2, 3> v1;
ex::vec<4, 5> v2;
ex::vec<2> v3;
auto r = ex::all(v1,v2,v3);
r.print();
This prints 7 7 3;
我要实现的是:
vecSum<vec<1,3,4>, vec<3>, vec<3,4,5>> z;
z::res.print(); and I expect 7 7 9
相反,我有这个错误:
error C2275: 'Ts': illegal use of this type as an expression
error C2119: 'res': the type for 'auto' cannot be deduced from an empty initializer
有人可以提示这里有什么问题吗?我知道我正在尝试将类型参数包 Ts
作为表达式传递,是否有解决方法或修复方法?
我在你的代码中发现了一些小问题...
- 展开
Ts
在vecSum
中你定义res
如下
static constexpr auto res = all(Ts);
你必须展开Ts
如下
// ...............................VVVVV
static constexpr auto res = all(Ts{}...);
std::index_sequence
包含 std::size_t
,而不是 int
,值
你的add()
定义如下
template<int...N, int...M, int ...S>
auto add(vec<N...>, vec<M...>, std::index_sequence<S...>)
但是 S...
值是 std::size_t
// ........................VVVVVVVVVVV
template<int...N, int...M, std::size_t ...S>
auto add(vec<N...>, vec<M...>, std::index_sequence<S...>)
或者模板推导不起作用。
constexpr
函数
如果 vecSum
必须是 constexpr
,您必须将所有必要的函数(add()
、all()
、operator+()
)定义为 constexpr
.
print() const
方法 vec::print()
更好 const
,因为你想打印一个 constexpr
vecSum::res
值。
以下是完整的编译修正示例
#include <utility>
#include <iostream>
#include <type_traits>
namespace ex {
template<int... N>
struct vec
{
static const int size = sizeof...(N);
void print() const {
((std::cout << N << " "), ...);
}
};
template<int...N, int...M, std::size_t ...S>
constexpr auto add(vec<N...>, vec<M...>, std::index_sequence<S...>) {
constexpr int arr1[sizeof...(S)]{ N... };
constexpr int arr2[sizeof...(S)]{ M... };
return vec<(arr1[S] + arr2[S])...>{};
}
template<int...N, int...M>
constexpr auto operator+(vec<N...> v1, vec<M...> v2) {
constexpr size_t size = std::max(sizeof...(N), sizeof...(M));
return add(v1, v2, std::make_index_sequence<size>{});
}
template<typename... Args>
constexpr auto all(Args... args) { return (... + args); }
template<typename... Ts>
struct vecSum
{
static constexpr auto res = all(Ts{}...);
};
}
int main ()
{
ex::vecSum<ex::vec<1,3,4>, ex::vec<3>, ex::vec<3,4,5>> z;
z.res.print();
}
我正在尝试创建可变 int
参数向量并对其执行 +
运算符。
例如:
vec<1,2,3> v1;
vec<4,5> v2;
auto res = v1+v2;
res.print(); // should print 5 7 3 vec<5,7,3> is the result.
现在我想创建结构 vecSum
,它将对提供给它的向量求和;
namespace ex {
template<int... N>
struct vec
{
static const int size = sizeof...(N);
void print() {
((std::cout << N << " "), ...);
}
};
template<int...N, int...M, int ...S>
auto add(vec<N...>, vec<M...>, std::index_sequence<S...>) {
constexpr int arr1[sizeof...(S)]{ N... };
constexpr int arr2[sizeof...(S)]{ M... };
return vec<(arr1[S] + arr2[S])...>{};
}
template<int...N, int...M>
auto operator+(vec<N...> v1, vec<M...> v2) {
constexpr size_t size = std::max(sizeof...(N), sizeof...(M));
return add(v1, v2, std::make_index_sequence<size>{});
}
template<typename... Args>
auto all(Args... args) { return (... + args); }
template<typename... Ts>
struct vecSum
{
static constexpr auto res = all(Ts);
};
}
这个测试工作正常:
ex::vec<1, 2, 3> v1;
ex::vec<4, 5> v2;
ex::vec<2> v3;
auto r = ex::all(v1,v2,v3);
r.print();
This prints 7 7 3;
我要实现的是:
vecSum<vec<1,3,4>, vec<3>, vec<3,4,5>> z;
z::res.print(); and I expect 7 7 9
相反,我有这个错误:
error C2275: 'Ts': illegal use of this type as an expression
error C2119: 'res': the type for 'auto' cannot be deduced from an empty initializer
有人可以提示这里有什么问题吗?我知道我正在尝试将类型参数包 Ts
作为表达式传递,是否有解决方法或修复方法?
我在你的代码中发现了一些小问题...
- 展开
Ts
在vecSum
中你定义res
如下
static constexpr auto res = all(Ts);
你必须展开Ts
如下
// ...............................VVVVV
static constexpr auto res = all(Ts{}...);
std::index_sequence
包含std::size_t
,而不是int
,值
你的add()
定义如下
template<int...N, int...M, int ...S>
auto add(vec<N...>, vec<M...>, std::index_sequence<S...>)
但是 S...
值是 std::size_t
// ........................VVVVVVVVVVV
template<int...N, int...M, std::size_t ...S>
auto add(vec<N...>, vec<M...>, std::index_sequence<S...>)
或者模板推导不起作用。
constexpr
函数
如果 vecSum
必须是 constexpr
,您必须将所有必要的函数(add()
、all()
、operator+()
)定义为 constexpr
.
print() const
方法 vec::print()
更好 const
,因为你想打印一个 constexpr
vecSum::res
值。
以下是完整的编译修正示例
#include <utility>
#include <iostream>
#include <type_traits>
namespace ex {
template<int... N>
struct vec
{
static const int size = sizeof...(N);
void print() const {
((std::cout << N << " "), ...);
}
};
template<int...N, int...M, std::size_t ...S>
constexpr auto add(vec<N...>, vec<M...>, std::index_sequence<S...>) {
constexpr int arr1[sizeof...(S)]{ N... };
constexpr int arr2[sizeof...(S)]{ M... };
return vec<(arr1[S] + arr2[S])...>{};
}
template<int...N, int...M>
constexpr auto operator+(vec<N...> v1, vec<M...> v2) {
constexpr size_t size = std::max(sizeof...(N), sizeof...(M));
return add(v1, v2, std::make_index_sequence<size>{});
}
template<typename... Args>
constexpr auto all(Args... args) { return (... + args); }
template<typename... Ts>
struct vecSum
{
static constexpr auto res = all(Ts{}...);
};
}
int main ()
{
ex::vecSum<ex::vec<1,3,4>, ex::vec<3>, ex::vec<3,4,5>> z;
z.res.print();
}