C++ 在c+中执行期间生成代码+;11
我正在用C++11编程,想知道是否有办法在执行过程中生成一些代码 例如,不要写:C++ 在c+中执行期间生成代码+;11,c++,C++,我正在用C++11编程,想知道是否有办法在执行过程中生成一些代码 例如,不要写: void b(int i){i+1} void c(int i){i-1} if(true) b() else{ c() } 有没有更直接的方法来说明如果是真的,那么将所有+替换为- 如果这个问题很愚蠢,请向您表示感谢和歉意。C++没有运行时代码生成,因为它是一种编译语言。 在这种情况下,可以将符号放入变量中(与多个变量一起使用) 例如 C++没有用于生成运行时代码的本机工具。当然,你可以从程序中调用C++编译器
void b(int i){i+1}
void c(int i){i-1}
if(true) b()
else{ c() }
有没有更直接的方法来说明如果是真的,那么将所有+替换为-
如果这个问题很愚蠢,请向您表示感谢和歉意。C++没有运行时代码生成,因为它是一种编译语言。 在这种情况下,可以将符号放入变量中(与多个变量一起使用) 例如
C++没有用于生成运行时代码的本机工具。当然,你可以从程序中调用C++编译器,然后动态加载结果二进制文件,并从中调用代码,但我怀疑这是解决问题的最佳方案。 如果你担心反复检查病情,你不应该担心。由于分支预测,现代CPU可能会很好地处理这个问题,即使是在一个紧密的循环中
最后,如果您真的想更动态地更改所采用的代码路径,可以使用函数指针和/或多态性和/或lambda 函数示例
多态性的一个例子 这里,我用
doIt
纯虚函数定义了一个基类。这两个子类重写doIt()
函数以执行不同的操作pOp
将根据cond
指向Add
或Sub
实例,因此当调用pOp->doIt()
时,将使用运算符的适当实现。在封面下,这基本上就是我在上面的例子中用函数指针所描述的,因此选择一个而不是另一个很大程度上是风格和/或其他设计约束的问题。他们的表现应该一样好
使用lambdas的示例 这与第一个使用函数指针的示例基本相同,但使用lambdas以更为C++11的方式完成(而且更为简洁) 或者,您可能更喜欢在lambda的主体内部设置条件,例如
auto d = [&](int i) { cond ? i+1 : i-1; }
...
d(i);
不一定能解决你的问题,但你可以使用 在
中的一个运算符上实例化的模板:
只有在lambdas中没有捕获时,这才有效;当有
没有捕获,lambda不仅生成具有
一个独特的类型,但也是一个函数。虽然不能使用
条件运算符使其变得比必要的更为详细,它仍然是
可能比必须在类之外定义函数更简单,
除非该函数可以作为模板实现,如我的第一个
例子。(我想你的实际情况可能会更糟
比您发布的示例更复杂。)
编辑:
关于lambdas,我试过:
auto f = c ? []( int i ) { return i + 1; } : []( int i ) { return i - 1; };
只是出于好奇。MSC++给了我预期的错误
信息:
没有从“someFunc::”到“someFunc::”的转换
但是g++毫无怨言地编译了它,typeid(f)
给出了“PFiiI”
,
我认为这是一个指向函数的指针。在这种情况下,我很确定
MSC++是正确的:标准说每个lambda都有
一个唯一的类型,并且每个类型都有一个转换运算符(在此
大小写)一个int(*)(int)
(因此两者可以转换为相同的
键入这就是带有的版本(如果有效)的原因。但是
条件运算符的规范要求
第二个操作数可以转换为第三个操作数的类型,反之亦然,
但结果必须是其中一个操作数的类型;不可能
第三种类型,两者都转换为。您可以重写函数以接受bool
参数,例如:void b(int i,bool j){return i+(j?1:-1);}
。这不需要运行时代码生成。不,没有办法。您需要一个编译时语句,在运行它之前,所有内容都必须在代码中编写。谢谢!这到底是什么意思?(j?1:-1)@MM。从技术上讲,有一种方法,这是一种非常复杂的方法,在这种情况下,这绝对是矫枉过正。(例如,见C++编写的JIT编译器)@ @ Pao <代码>:<代码>是三元运算符。它的形式是条件?如果为真:如果为假
。如果conditional
的计算结果为true,则表达式的计算结果为If\u true
,否则它的计算结果为If\u false
。请注意,在计算整个表达式时,实际上只计算if_true
和if_false
中的一个,因为例如当conditional
为true时,不需要计算if_false的表达式。演示如何使用lambda表达式执行此操作是否也有用?@sjdowling这是个好主意,因为这是C++11。给我一分钟,你试过兰博达斯吗?第一个示例不会编译,因为条件运算符的第二个和第三个操作数没有公共类型。(每个lambda都有一个唯一的类型。)(第二个示例每次都会进行测试。)关于lambda的更新:根据标准(我实际上在看N3797;这些东西经常变化),您的第一个lambda示例不应该编译。根据VS 2013,情况并非如此。但是g++4.8.3(当然是--std=c++11
)是这样的。不过,这看起来像是g++中的一个bug。@James-Oh?真是个惊喜。事实上,我并不经常和兰姆达斯合作,所以我不知道其中的复杂之处。你知道问题是什么以及如何纠正它吗?
class Operator
{
public:
Operator() {}
virtual ~Operator() {}
virtual void doIt(int i) = 0;
};
class Add : public Operator
{
public:
virtual void doIt(int i) { i+1; }
};
class Sub : public Operator
{
public:
virtual void doIt(int i) { i-1; }
};
...
Operator *pOp = cond ? new Add() : new Sub();
...
pOp->doIt(i);
...
delete pOp;
auto d = cond ? [](int i) { i+1; }
: [](int i) { i-1; };
...
d(i);
auto d = [&](int i) { cond ? i+1 : i-1; }
...
d(i);
template <typename Op>
int
func( int i )
{
return Op()( i, 1 );
}
int (*f)( int i ) = condition ? &func<std::plus> : &func<std::minus>;
// ...
i = f( i );
int (*f)( int i );
if ( condition ) {
f = []( int i ) { return i + 1; }
} else {
f = []( int i ) { return i - 1; }
}
auto f = c ? []( int i ) { return i + 1; } : []( int i ) { return i - 1; };
no conversion from 'someFunc::<lambda_21edbc86aa2c32f897f801ab50700d74>' to 'someFunc::<lambda_0dff34d4a518b95e95f7980e6ff211c5>'