我想将格式化参数传递Args给Format函数.我找到了一些例子,但是我无法找到如何在TVarRec成员中分配字符串常量.以下代码在编译时失败E2089 Invalid typecast.
procedure TForm1.Button1Click(Sender: TObject);
var Arguments: array of TVarRec;
begin
SetLength(Arguments, 2);
Arguments[0].VInteger := 111;
Arguments[1].VAnsiString := PAnsiString('Text'); // I want to set this member
ShowMessage(Format('Decimal: %d, String: %s', Arguments));
end;
Run Code Online (Sandbox Code Playgroud)
任何人都可以建议我如何将字符串(或AnsiString)常量设置为TVarRec成员?我正在使用Delphi 2009.
非常感谢
static const int a = 42;
static const int b = a;
Run Code Online (Sandbox Code Playgroud)
我希望在这样的代码中出现编译错误.初始值设定项必须是常量表达式或字符串文字.存储在int具有const类型限定符类型的对象中的值不是常量表达式.
我编译-Wall -Wextra -pedantic,甚至与-ansi.然后:
error: initializer element is not constant令人惊讶的是,以下内容:
static const char * const a = "a";
static const char * const b = a;
Run Code Online (Sandbox Code Playgroud)
error: initializer element is not constanterror: initializer element is …constexpr int func(int const& rf){
return rf;
}
int main(){
constexpr int value = func(0);
}
Run Code Online (Sandbox Code Playgroud)
考虑上面的代码,变量value应该由一个常量表达式初始化,即func(0),它首先应该是一个核心常量表达式。为了判断表达式是否func(0)是核心常量表达式,将应用以下规则,即:
expr.const#2.7
表达式 e 是核心常量表达式,除非对 e 的求值遵循抽象机的规则,将求值以下表达式之一:
左值到右值的转换,除非它应用于
[...], 或者
(2.7.4) 文字类型的非易失性泛左值,指的是其生命周期开始于 e 求值期间的非易失性对象;
尽管lvalue-to-rvalue conversion应用了rf并且这种转换满足了要点(2.7.4),但是,请看一下下一段,即:
expr.const#2.11
引用引用类型的变量或数据成员的 id 表达式,除非引用具有前面的初始化并且
- (2.11.1) 它用常量表达式初始化,或者,
- (2.11.2) 其生命周期开始于 e 的评估内;
我不知道这句话的真正preceding initialization含义是什么?这是否意味着变量应该在使用之前进行初始化,或者意味着在变量的声明中应该有一个初始值设定项。无论如何,在将 应用于lvalue-to-rvalue conversion glvalue之前rf,应该评估 glvaluerf以确定对象的身份,该身份由以下规则决定:
左值是一个表达式,其计算确定对象、位域或函数的标识。
这意味着不仅应遵守项目符号 [expr.const#2.7],还应遵守 [expr.const#2.11]。
因为 id-expressionrf是引用类型。因此,为了使表达式func(0)成为核心常量表达式,id-表达式rf必须有一个前置的初始化 …
这是我的代码:
class agg_t1{
int x; // private non-static data menber
};
class agg_t2{
agg_t2(){} // user-provided constructor
};
constexpr void ce1(agg_t1 arg){}; // OK
constexpr void ce2(agg_t2 arg){}; // ERROR: parameter type 'agg_t2' is not a literal type
Run Code Online (Sandbox Code Playgroud)
constexpr 函数的定义应满足以下要求: ...
- 它的每个参数类型都应该是文字类型;...
如果类型是文字类型,则它是: ...
- 它可以是闭包类型、聚合类型,或者......
我理解为什么agg_t2不是文字类型的原因是,它违反了规则dcl.init.aggr#1.1:
聚合是一个数组或一个类......
- 没有用户声明或继承的构造函数...
我认为agg_t1可能不是文字类型,因为它也违反了规则dcl.init.aggr#1.1:
聚合是一个数组或一个类......
- 没有私有或受保护的直接非静态数据成员...
然而......编译器结果告诉我我对 的假设是错误的agg_t1。
如果agg_t1的私有数据成员x …
c++ language-lawyer constant-expression constexpr constexpr-function
如果我没记错的话,用户定义的文字的参数在编译时总是已知的。在 C++20 中,您可以使用强制函数在编译时执行,consteval从而throw生成编译时错误。
#include <limits>\n\nconsteval int operator""_int(unsigned long long int v) {\n if (std::numeric_limits<int>::max() < v) {\n throw "out of range";\n }\n return static_cast<int>(v);\n}\n\nint main() {\n return 1\'000\'000\'000\'000_int;\n}\nRun Code Online (Sandbox Code Playgroud)\n$ g++ -std=c++20 main.cpp\nmain.cpp: In function \xe2\x80\x98int main()\xe2\x80\x99:\nmain.cpp:11:12: in \xe2\x80\x98constexpr\xe2\x80\x99 expansion of \xe2\x80\x98operator""_int(1000000000000)\xe2\x80\x99\nmain.cpp:5:9: error: expression \xe2\x80\x98<throw-expression>\xe2\x80\x99 is not a constant expression\n 5 | throw "out of range";\n | ^~~~~~~~~~~~~~~~~~~~\nRun Code Online (Sandbox Code Playgroud)\n根据我的经验,编译时错误通常比运行时错误更可取。
\n如果必须在定义中调用其他不是 的函数constexpr,那么consteval显然不是一个选项。但除了这个例子,我想不出有什么理由不使用consteval.
还有其他原因不将用户定义的文字标记为 吗consteval …
c++ constant-expression user-defined-literals c++20 consteval
在一些C++源代码中,我看到表达式结果可以保存为常量崇敬.像这样:
const int &x = y + 1;
Run Code Online (Sandbox Code Playgroud)
这是什么意思?有没有这方面的文件?我找不到..
对我来说,它似乎相当于:
const int x = y + 1;
Run Code Online (Sandbox Code Playgroud)
因为程序的结果保持不变.它真的相同吗?
如果是,为什么语言允许第一种方式来编写它?看起来很混乱.
如果没有什么区别?
我有以下几种类型
type StatusCode =
| OK = 200
| NoContent = 204
| MovedTemp = 301
| MovedPerm = 302
| SeeOther = 303
| NotModified = 304
| NotFound = 404
| ServerError = 500
[<Literal>]
let NoBodyAllowedStatusCodes = [StatusCode.NoContent; StatusCode.NotModified]
Run Code Online (Sandbox Code Playgroud)
我得到一个编译时错误,说:
这不是有效的常量表达式或自定义属性值
我无法弄清楚这里有什么问题.
我需要将字符串转换为Literal,以便将其作为参数传递给CsvProvider.但我无法做到.下面的代码运行没有问题:
open System.IO
open FSharp.Data
open FSharp.Data.JsonExtensions
let charSwitch (a: char) b x =
if x = a then
b
else
x
let jsonDataPath = Path.Combine(__SOURCE_DIRECTORY__, @"data\fractal.json")
let jsonData = JsonValue.Load(jsonDataPath)
/// Path with traded assets
let trp = ((jsonData?paths?tradedAssets).AsString() |> Core.String.map (charSwitch '\\' '/')).ToString()
printfn "trp is a standard string: %s" trp
// trp is a standard string: H:/Dropbox/Excel/Data/Fractal/Traded.csv
Run Code Online (Sandbox Code Playgroud)
但是,添加以下两行时
[<Literal>]
let tradedPath = trp
Run Code Online (Sandbox Code Playgroud)
最后我得到了消息This is not a valid constant expression or custom attribute value.
我甚至试图复制trp,但这没有帮助. …
以下(公认的做作)C程序无法编译:
int main() {
const int array[] = {1,2,3};
static int x = array[1];
}
Run Code Online (Sandbox Code Playgroud)
使用gcc(或Microsoft的CL.EXE)编译上述C源文件时,出现以下错误:
error: initializer element is not constant
static int x = array[1];
^
Run Code Online (Sandbox Code Playgroud)
这种简单直观的语法肯定是有用的,所以这似乎应该是合法的,但显然它不是.当然,我不是唯一一个对这种明显愚蠢的限制感到沮丧的人.我不明白为什么这是不允许的 - 通过使这个有用的语法非法,C语言试图避免什么问题?
看起来它可能与编译器为初始化生成汇编代码的方式有关,因为如果删除"static"关键字(使得变量"x"在堆栈上),那么它编译得很好.
然而,另一个奇怪的事情是它在C++中编译得很好(即使使用static关键字),但在C中却没有.因此,C++编译器似乎能够生成必要的汇编代码来执行这样的初始化.
编辑:相信戴维斯 - 为了安抚SO权力 - 我会寻求以下类型的事实信息来回答这个问题:
是否有支持这些语义的遗留代码会破坏?
这些语义是否已经正式提交给标准委员会?
有没有人有理由拒绝这些语义的允许?
我有一个Assert用于评估断言的函数:
如果前提条件在运行时失败,该函数将输出一条错误消息并终止程序。
如果常量表达式中的前提条件失败,则会导致编译时错误。
我希望当断言在常量计算表达式中失败时,该函数也会生成编译时错误:
const int a = (Assert(false),0); //generate a runtime error
//=> I would like it generates a compile time error
Run Code Online (Sandbox Code Playgroud)
我考虑过使用std::is_constant_evaluated:compiler-explorer
#include <type_traits>
using namespace std;
void runtime_error();
constexpr void compile_time_error(){} //should generates a compile time error
constexpr void Assert(bool value){
if (value) return;
if (is_constant_evaluated())
compile_time_error();
else
runtime_error();
}
void func(){
const int a = (Assert(false),0);
}
Run Code Online (Sandbox Code Playgroud)
我只使用 GCC,我寻找了一个会导致编译时错误的内置函数,该函数是 constexpr,但没有找到。
是否有任何技巧可以在可以常量求值的表达式中获得编译时错误?