gpt4 book ai didi

static_assert usage: What am I missing here?(STATIC_ASSERT用法:我在这里遗漏了什么?)

翻译 作者:bug小助手 更新时间:2023-10-26 22:39:36 27 4
gpt4 key购买 nike



I would like to reference two earlier posts:

我想引用两个较早的文章:


why-is-comparing-two-parameters-of-a-constexpr-function-not-a-constant-condition

Why-is-comparing-two-parameters-of-a-constexpr-function-not-a-constant-condition


how-does-this-function-template-deduce-the-size-of-an-array

How-does-this-function-template-deduce-the-size-of-an-array


In the first discussion, it has been pointed out that the compilation error

在第一个讨论中,已经指出了编译错误


error: non-constant condition for static assertion

is due to the fact that the constexpr function under consideration could be invoked with arguments evaluated during run-time.

这是因为可以使用在运行时计算的参数来调用所考虑的constexpr函数。


In the second discussion, it has been pointed out that the template function method for getting at the size of the template array, works due to template argument type deduction by the compiler, which happens during compilation.

在第二个讨论中,已经指出,用于获取模板数组大小的模板函数方法是由于编译器在编译期间发生的模板参数类型推断而起作用的。


The following code gives me this error for static assertion:

下面的代码给出了静态断言的这个错误:


In file included from main.cpp:1:
classA.h: In instantiation of ‘void doSomething(A<T> (&)[2]) [with T = int; array2As<T> = A<int> [2]]’:
main.cpp:6:18: required from here
classA.h:65:20: error: non-constant condition for static assertion
65 | static_assert(2 == sz, "Compilation error: array must have exactly 2 elements");
| ~~^~~~~
compilation terminated due to -Wfatal-errors

//classA.h

#include <type_traits>
#include <cstddef>
//#include <iterator>
#include <iostream>

using std::is_same;
//using std::size;
using std::size_t;
using std::cout;
using std::endl;

template<typename T> class A;
template<typename T>
using array2As = A<T>[2];

template<typename T>
void doSomething (array2As<T>&);

template<template<typename>class A, typename T, size_t N>
constexpr size_t cal_size(const A<T>(&)[N]){
return N;
}

template<typename T>
class A{
public:
A(T);
private:
friend void doSomething<>(array2As<T>&);
A()=delete;
A(const A&)=delete;
A& operator=(const A&)=delete;
T elem;
};

template<typename T>
A<T>::A(T elem){
static_assert(is_same<T,int>::value || is_same<T,double>::value, "Compilation error: type must be int or double");
this->elem = elem;
}

template<typename T> void doSomething (array2As<T>& a){
auto sz = cal_size(a);
cout << sz << endl;
static_assert(2 == sz, "Compilation error: array must have exactly 2 elements");

const auto& obj1 = a[0];
cout << obj1.elem << endl;
const auto& obj2 = a[1];
cout << obj2.elem << endl;
return;
}

//main.cpp

#include "classA.h"

int main (){

array2As<int> a = {A(5),A(7)};
doSomething<int>(a);
array2As<double> b = {A(1.2),A(6.3)};
doSomething<double>(b);

return 0;
}

The methods involved, i.e., cal_size() and doSomething() are function templates themselves, so going by the explanation in the second post, the value stored inside the variable sz as returned from cal_size() should be a compile time constant.

所涉及的方法,即cal_Size()和DoSomething()本身就是函数模板,因此按照第二篇文章中的解释,存储在变量sz中的值应该是一个编译时间常数,该值是从cal_Size()返回的。


So why is it that I am still getting this error?

那么,为什么我仍然收到这个错误呢?


TIA

Tia


更多回答

cal_size(a) is (currently) a constant expression, but you store its result into a non-const(expr) variable which can have its value changed at any point at runtime, so sz isn't usable in constant expressions. Add constexpr on its declaration. And then it will likely still fail because there is a recent defect report against the standard that your compiler likely hasn't implemented yet before which cal_size(a) was not a constant expression specifically because a is a reference.

CAL_SIZE(A)(当前)是一个常量表达式,但是您将其结果存储到一个非常数(Expr)变量中,该变量可以在运行时的任何时刻更改其值,因此sz在常量表达式中不可用。在其声明上添加constexpr。然后,它可能仍然会失败,因为最近有一个针对标准的缺陷报告,您的编译器可能还没有实现它,在此之前,cal_size(A)不是一个常量表达式,特别是因为a是一个引用。

@user17732522 I tried changing sz to constexpr and ran into the error that you are referring to

@user17732522我尝试将sz更改为constexpr,但遇到了您提到的错误

@user17732522 this is in spite of changing the parameter type of doSomething to const...any thoughts?

@user17732522这是尽管将DoSomething的参数类型更改为const...您有什么想法?

As long as your compiler doesn't implement the DR, it is impossible to calculate the size by passing a by-reference which is necessary for a built-in array to even have the type information. Passing a std::array by-value would work. If you still want to do it your way, you need to operate directly on the type of a, not a itself. E.g. by using std::extent instead of your cal_size.

只要您的编译器不实现DR,就不可能通过传递By-Reference来计算大小,而By-Reference是内置数组拥有类型信息所必需的。按值传递std::数组会起作用。如果您仍然想按自己的方式操作,则需要直接对a的类型进行操作,而不是对a本身进行操作。例如,使用std::Extent而不是您的cal_Size。

In fact a generalization of your issue was the first question I posted myself here: stackoverflow.com/questions/70482497/…

事实上,我在这里发布的第一个问题是对您的问题的概括:Stackoverflow.com/Questions/70482497/…

优秀答案推荐
更多回答

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com