我认为D static if是一个有趣的语言功能.这提示了我的问题:是否还有编译语言的其他示例,其中编译器具有强大的代码概念,并且有语言工具可以访问它们?
例如,此代码提供类似于reprPython的代码:
char[] repr(T)(T value) {
static if (is(typeof(value.__repr__))) { // class T provides a "repr()" method
return value.__repr__();
} else static if (is(T:string)) {
return `"` ~ value ~ `"`;
// ...other cases...
} else {
return toString(value);
}
}
Run Code Online (Sandbox Code Playgroud)
我认为这很酷,因为它允许一种不同的,更通用的方法来实现重载,这是一种让代码更加动态的内部方式,与这样的功能相比.例如,编译器知道我的类有多少字段,但是在大多数语言中,我的代码无法在编译时访问该信息.
CAVEAT:最后一段中有意见,但我只是想为我的问题提供一些动力和澄清,而不是引起争议.我只是想知道是否有其他编译语言有这样的功能.
问题简而言之:
如何static if在普通的c ++中实现c ++ 11中提出的功能?
历史和原始问题:
最近我提出了这样的问题.我需要一个Sender类似界面的类
class Sender
{
void sendMessage( ... );
void sendRequest( ... );
void sendFile( ... );
// lots of different send methods, not important actually
}
Run Code Online (Sandbox Code Playgroud)
在某些情况下,我需要创建一个DoubleSender,即这个类的一个实例,它会调用它的方法两次,即在调用时,比方说,一个sendMessage(...)方法,必须发送两次相同的消息.
我的解决方案:
第一种方法:
拥有一名isDouble成员,并在每次方法调用结束时进行检查
sendMessage(...) { ... if( isDouble ) { sendMessage( ... ); }
Run Code Online (Sandbox Code Playgroud)
好吧,我不想要这个,因为实际上我最近需要双重发布,这部分时间关键部分的代码将是98%被动.
第二种方法:从中
继承一个类,并实现其方法,如:DoubleSenderSender
void DoubleSender::sendMessage( ... )
{
Sender::sendMessage(...);
Sender::sendMessage(...);
}
Run Code Online (Sandbox Code Playgroud)
嗯,这是可以接受的,但需要很多不愉快的代码空间(真的很多,因为有很多不同的send..方法.
第三种方法:
想象一下我使用的是c ++ 11 :).然后我可以使这个类通用,并根据tempalte参数生成代码的必要部分 …
我正在测试各种优化的组合,对于这些,我需要一个静态的,如果在描述http://channel9.msdn.com/Events/GoingNative/GoingNative-2012/Static-If-I-Had-a-Hammer启用并禁用特定的优化.if(const-expr)并不总是有效,因为某些优化涉及更改数据布局,而这在功能范围内无法完成.
基本上我想要的是这个:
template<bool enable_optimization>
class Algo{
struct Foo{
int a;
if(enable_optimization){
int b;
}
void bar(){
if(enable_optimization){
b = 0;
}
}
};
};
Run Code Online (Sandbox Code Playgroud)
(是的,在我的情况下,从数据布局中删除b的较小内存占用量是相关的.)
目前我正在使用非常糟糕的黑客伪装它.我正在寻找一种更好的方法.
档案啊
#ifndef A_H
#define A_H
template<class enable_optimization>
class Algo;
#include "b.h"
#endif
Run Code Online (Sandbox Code Playgroud)
文件bh(此文件是从Python脚本自动生成的)
#define ENABLE_OPTIMIZATION 0
#include "c.h"
#undef
#define ENABLE_OPTIMIZATION 1
#include "c.h"
#undef
Run Code Online (Sandbox Code Playgroud)
文件ch
template<>
class Algo<ENABLE_OPTIMIZATION>{
struct Foo{
int a;
#if ENABLE_OPTIMIZATION
int b;
#endif
void bar(){
#if ENABLE_OPTIMIZATION
b = 0;
#endif
}
};
};
Run Code Online (Sandbox Code Playgroud)
有谁知道更好的方法吗?从理论上讲,它可以使用模板元编程完成,起初我使用它.至少我使用它的方式是屁股的痛苦,并导致完全不可读和臃肿的代码.使用上面的hack可以显着提高生产力.
编辑:我有几个优化标志,这些互动.
一些通常的模板专业化如下:
template<class T>
class C
{
void common() { ... }
void f2 = delete;
};
template<>
class C<int>
{
void common() { ... }
void f1() { ... }
};
Run Code Online (Sandbox Code Playgroud)
可以表示static_if为:
template<class T>
class C
{
void common() { ... }
static_if(std::is_same<T, int>::value)
{
void f1( ) { ... }
}
else
{
void f2( ) = delete;
}
}
Run Code Online (Sandbox Code Playgroud)
这些是直接竞争的功能吗?模板专业化static_if可以做些什么不可以吗?似乎static_if可以做模板专业化所能做的一切,还有更多.
暂且不说:我不喜欢static_if在这种情况下,因为它可能使得在任何特定情况下你可以使用界面的哪些部分是不明显的.在某些情况下,模板特化仍然可以提供更清晰的语法.
请考虑以下代码:
static if (!is(MyStruct))
{
struct MyStruct
{
}
}
static if (is(MyStruct))
{
static assert(0);
}
Run Code Online (Sandbox Code Playgroud)
我最初的理解是,声明的顺序(在全球范围内)在D中无关紧要.
但是,在这种情况下,static ifs 的顺序决定了程序是否编译.
因此,D的编译时评估阶段是程序性特征(如C/C++),声明性特征还是其他什么?目前是什么,计划是什么(如果两者不同)?
我刚刚意识到,问题甚至还没有结束.一,会发生什么static if用途.tupleof枚举当前模块的成员,并创建同一类型的问题?
我希望能够避免在条件为false时调用函数,这在编译时已知.现在我使用这样的东西:
template<bool Enabled>
void fun(params)
{
//do nothing
}
template<>
void fun<true>(params)
{
//do something with params.
}
Run Code Online (Sandbox Code Playgroud)
params即使函数体是空的,我也不喜欢这种方法.
我想要一个解决方案,当根本没有调用该函数时,当条件为假时,不会对params进行求值(这可能在第一种情况下使用空函数进行优化,但我不能认为这是真的.编译器).
这甚至可能吗?
是否可以在 C99 中实现 static_if?
#define STATIC_IF(COND, ...) \
if (COND) MACRO1(__VA_ARGS__); \
else MACRO2(__VA_ARGS__);
Run Code Online (Sandbox Code Playgroud)
我如何STATIC_IF(…)在这里正确实施?根据COND参数,要么应该传递给MACRO1要么MACRO2,但两个宏的参数看起来不同。COND是静态可测试的,类似于sizeof (…) > 42.
#if COND然后#define STATIC_IF MACRO1……不适用于我的用例。static-if ×7
c++ ×4
static ×3
c++11 ×2
d ×2
c ×1
c++14 ×1
c99 ×1
compile-time ×1
declarative ×1
if-statement ×1
optimization ×1
performance ×1
templates ×1
terminology ×1