如果我写
enum chars = digits ~ uppercase;
Run Code Online (Sandbox Code Playgroud)
字符串是否会在编译时连接?我假设它会.如果我用字符串文字或CTFE函数替换它,我无法测量任何显着的性能差异(甚至称它为一亿次).如果我用const替换enum,我确实会有所不同.我被告知这样编写效率很低.我觉得这很方便,我看不出效率低下.(顺便说一句,该行是一个递归调用的函数).
完整代码(转换为具有不同基数的数字系统)
import std.string;
string toBase(long n, int b)
in {
assert(2 <= b && b <= 35);
} body {
static string sign;
if (n < 0) {
n *= -1;
sign = "-";
}
enum chars = digits ~ uppercase;
size_t r = cast(size_t)(n % b);
if (n == r) {
return sign ~ chars[r];
}
return toBase((n - r) / b, b) ~ chars[r];
}
Run Code Online (Sandbox Code Playgroud)
编辑:更新的代码,以回应评论,与问题无关
string toBase(long n, int …Run Code Online (Sandbox Code Playgroud) 有没有办法在常量表达式中使用函数地址?
void foo()
{}
int main()
{
static_assert(&foo, "test error");
}
Run Code Online (Sandbox Code Playgroud)
这不会编译.
错误C2057:预期的常量表达式
这背后的意图是我想在编译时比较两个函数地址.
我正在尝试包装Windows API函数以在我选择时检查错误.正如我在之前的SO问题中发现的那样,我可以使用模板函数来调用API函数,然后调用GetLastError()以检索它可能设置的任何错误.然后,我可以将此错误传递给我的Error班级让我知道.
这是模板函数的代码:
template<typename TRet, typename... TArgs>
TRet Wrap(TRet(WINAPI *api)(TArgs...), TArgs... args)
{
TRet ret = api(args...);
//check for errors
return ret;
}
Run Code Online (Sandbox Code Playgroud)
使用这个我可以有如下代码
int WINAPI someFunc (int param1, BOOL param2); //body not accessible
int main()
{
int ret = someFunc (5, true); //works normally
int ret2 = Wrap (someFunc, 5, true); //same as above, but I'll get a message if there's an error
}
Run Code Online (Sandbox Code Playgroud)
这非常有效.但是,有一个可能的问题.采取这个功能
void WINAPI someFunc();
Run Code Online (Sandbox Code Playgroud)
将其转换为模板函数时,它看起来如下:
void Wrap(void(WINAPI *api)())
{
void ret …Run Code Online (Sandbox Code Playgroud) 我想为Data.Map创建一个特殊的智能构造函数,对键/值对关系的类型有一定的约束.这是我试图表达的约束:
{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, DataKinds #-}
data Field = Speed | Name | ID
data Value = VFloat Float | VString ByteString | VInt Int
class Pair f b | f -> b where
toPair :: f -> b -> (f, b)
toPair = (,)
instance Pair Speed (VFloat f)
instance Pair ID (VInt i)
Run Code Online (Sandbox Code Playgroud)
对于每个字段,只应该与其关联的一种类型的值.就我而言,一个Speed字段映射到一个字段是没有意义的ByteString.一个Speed字段应该唯一映射到一个Float
但是我收到以下类型错误:
Kind mis-match
The first argument of `Pair' should have kind `*',
but `VInt' has kind …Run Code Online (Sandbox Code Playgroud) haskell compile-time type-constraints functional-dependencies gadt
是static_cast<T>(...)在编译时还是在运行时完成的事情?我用Google搜索了但我得到了不同的答案.
此外,dynamic_cast<T>(...)显然是运行时 - 但是呢reinterpret_cast<T>(...)?
请考虑以下代码:
template <unsigned int N>
struct myclass
{
unsigned int f() {return N;}
unsigned int g() {static_assert(N > 0, ""); return N-1;}
};
Run Code Online (Sandbox Code Playgroud)
问题:我是否保证以下代码将编译:
myclass<0> c;
c.f();
Run Code Online (Sandbox Code Playgroud)
但以下不会:
myclass<0> c;
c.f();
c.g();
Run Code Online (Sandbox Code Playgroud) 我刚试过
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils;
begin
{$IFDEF CONSOLE}
beep;
{$ENDIF}
end.
Run Code Online (Sandbox Code Playgroud)
并期望beep在运行期间听到,但不是.但是,以下测试有效:
if IsConsole then
beep;
Run Code Online (Sandbox Code Playgroud)
为什么编译时测试不起作用?据我所知,从这份文件来看,它确实应该有效.
delphi conditional-compilation console-application compile-time
几天前,我询问编译器决定是否在编译期间计算constexpr函数.
事实证明,只有在编译时才会评估constexpr,如果所有参数都是常量表达式,并且您指定给它的变量也是常量表达式.
template<typename base_t, typename expo_t>
constexpr base_t POW(base_t base, expo_t expo)
{
return (expo != 0 )? base * POW(base, expo -1) : 1;
}
template<typename T>
void foobar(T val)
{
std::cout << val << std::endl;
}
int main(int argc, char** argv)
{
foobar(POW((unsigned long long)2, 63));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果我被告知是真的,这个代码示例是非常不实际的,因为foobar不接受constexpr(由于某种原因你不能使用consexpr作为参数),POW在运行时被评估,即使它可能是可能的在编译期间计算它.强制编译时评估的明显解决方案是:
auto expr = POW((unsigned long long)2, 63);
foobar(expr);
Run Code Online (Sandbox Code Playgroud)
然而,这迫使我使用额外的代码行,每次我想确保在编译时评估constexpr时都不需要这样做.为了使这更方便一点,我想出了以下可疑的宏:
#define FORCE_CT_EVAL(func) [](){constexpr auto ___expr = func; return std::move(___expr);}()
foobar(FORCE_CT_EVAL(POW((unsigned long long)2, 63)));
Run Code Online (Sandbox Code Playgroud)
尽管它工作得很好,但我觉得好像有些不对劲.创建匿名lambda会影响性能吗?通过rvalue引用返回实际上是将表达式移动到函数参数吗?std :: move如何影响性能?有没有更好的单线解决方案呢?
有人可以向我解释为什么ArrayIndexOutOfBoundsException是运行时异常而不是编译时错误?在明显的情况下,当索引为负数或大于数组大小时,我不明白为什么它不能是编译时错误.
编辑:特别是在编译时已知数组的大小甚至索引,例如,int[] a = new int[10]; a[-1]=5;这应该是编译错误.
我真的很欣赏 Raku 的&?BLOCK变量——它让你在一个未命名的块内递归,这可能非常强大。例如,这是一个简单的内联匿名阶乘函数:
{ when $_ ? 1 { 1 };
$_ × &?BLOCK($_ - 1) }(5) # OUTPUT: «120»
Run Code Online (Sandbox Code Playgroud)
但是,在更复杂的情况下使用时,我对它有一些疑问。考虑这个代码:
{ say "Part 1:";
my $a = 1;
print ' var one: '; dd $a;
print ' block one: '; dd &?BLOCK ;
{
my $a = 2;
print ' var two: '; dd $a;
print ' outer var: '; dd $OUTER::a;
print ' block two: '; dd &?BLOCK;
print "outer block: "; dd &?OUTER::BLOCK …Run Code Online (Sandbox Code Playgroud) compile-time ×10
c++ ×5
c++11 ×4
casting ×1
class ×1
compilation ×1
constexpr ×1
d ×1
delphi ×1
evaluation ×1
gadt ×1
haskell ×1
java ×1
raku ×1
rakudo ×1
runtime ×1
typechecking ×1