我刚刚遇到这种奇怪的C/C++语法:
#include <stdio.h>
int main() {
printf("%s",
({
static char b__[129];
b__[0] = 55;
b__[1] = 55;
b__[2] = 0;
b__;
})
);
}
Run Code Online (Sandbox Code Playgroud)
这使用gcc和g ++编译并运行良好(4.5.2).这是我第一次看到这样的东西,我想知道这种语法究竟意味着什么.我试过谷歌它,但我不知道这个结构被称为什么.
好的,有一个关键字,我故意远离标签和标题.这是"Android",但那是因为即使该项目是在Android中,我也不认为我的问题与它有任何关系,我不想在没有Android经验的情况下吓唬人.
所以,swig的常见问题.我在C++类中有一个虚方法,我通过director在类中添加该功能使其在Java中可重载,并且它可以工作.问题是该方法接收的多态参数也在java端扩展,并且在Java中的虚方法调用期间,该对象带有所有多态信息被剥离.
提出确切的情况; 我正在用C++编写游戏引擎,我想在Java中愉快地使用它.游戏引擎有一个GameObject类,它注册CollisionListeners,当碰撞引擎检测到碰撞事件时,它调用collidedWith(GameObject & collidee)所有已注册collisionListener的方法,通过它们与碰撞的对象传递它们.
class CollisionListener {
public:
virtual bool collidedWith(GameObject &){};
~CollisionListener(){} // I know this needs to be virtual but let's forget about that now
};
Run Code Online (Sandbox Code Playgroud)
我正在GameObject使用以下接口文件将该类与类一起暴露给javaBridge.i
%module(directors="1") Bridge
%feature("director") CollisionListener;
%include "CollisionListener";
%feature("director") GameObject;
%include "GameObject.h"
Run Code Online (Sandbox Code Playgroud)
现在,当我继承CollisionListenerjava和重载时collidedWith,它会被一个java端GameObject对象调用.例如,如果我从java侧GameObject类继承并定义一个Bullet类,当这个项目符号与另一个带有监听器的对象发生冲突时,在collidedWith方法调用中,我收到的所有内容都是裸的GameObject,因此(object instanceof Bullet)不起作用.毫不奇怪,我已经挖出了swig生成BridgeJNI.java并发现了这个:
public static boolean SwigDirector_CollisionListener_collidedWith(CollisionListener self, …Run Code Online (Sandbox Code Playgroud) 我经常使用boost.lambda(和phoenix)在C++中定义lambda函数.我非常喜欢它们的多态属性,它们表示的简单性以及它们在C++中进行函数式编程的方式变得如此简单.在某些情况下,它甚至更清晰,更易读(如果您习惯于阅读它们),可以使用它们来定义小函数并在静态范围内命名它们.
存储这些类似于传统功能的功能的方法最多的是捕获它们 boost::function
const boost::function<double(double,double)> add = _1+_2;
Run Code Online (Sandbox Code Playgroud)
但问题是这样做的运行时效率低下.即使add这里的函数是无状态的,返回的lambda类型也不是空的并且它sizeof大于1(因此boost::function默认的ctor和copy ctor将涉及new).我真的怀疑编译器或boost方面有一种机制来检测这种无状态并生成相当于使用的代码:
double (* const add)(double,double) = _1+_2; //not valid right now
Run Code Online (Sandbox Code Playgroud)
当然可以使用c ++ 11 auto,但是变量不能在非模板化的上下文中传递.我终于设法做了我想要的,使用以下方法:
#include <boost/lambda/lambda.hpp>
using namespace boost::lambda;
#include <boost/type_traits.hpp>
#include <boost/utility/result_of.hpp>
using namespace boost;
template <class T>
struct static_lambda {
static const T* const t;
// Define a static function that calls the functional t
template <class arg1type, class arg2type>
static typename result_of<T(arg1type,arg2type)>::type
apply(arg1type arg1,arg2type arg2){
return (*t)(arg1,arg2);
} …Run Code Online (Sandbox Code Playgroud) 正如标题所说,我有兴趣在Show a我拥有的环境中使用Show (a,b).GADT很容易出现这个问题如下:
data PairOrNot a where
Pair :: (b,c) -> PairOrNot (b,c)
Not :: a -> PairOrNot a
showFirstIfPair :: Show a => PairOrNot a -> String
showFirstIfPair (Not a) = show a
showFirstIfPair (Pair (b,c)) = show b
Run Code Online (Sandbox Code Playgroud)
错误是:
Could not deduce (Show b) arising from a use of ‘show’
from the context (Show a)
bound by the type signature for
showFirstIfPair :: Show a => PairOrNot a -> String
at app/Main.hs:24:20-50
or from …Run Code Online (Sandbox Code Playgroud) 我有两个线程试图锁定相同的boost::mutex.其中一个线程是连续处理一些数据,另一个是周期性地显示当前状态.根据我的意图,处理线程非常频繁地释放锁并重新获取它,以便显示线程可以在需要时接入并获取它.所以,显然,我希望显示线程在下一次由进程线程释放时获取锁.但是,它没有这样做,相反,它等待锁定并且仅在来自进程线程的许多锁定释放循环之后获取它.
请检查说明我的问题的最小例子:
#include <boost/thread.hpp>
#include <iostream>
using namespace std;
using namespace boost;
mutex mut;
void process() {
double start = time(0);
while(1) {
unique_lock<mutex> lock(mut);
this_thread::sleep(posix_time::milliseconds(10));
std::cout<<".";
if(time(0)>start+10) break;
}
}
int main() {
thread t(process);
while(!t.timed_join(posix_time::seconds(1))) {
posix_time::ptime mst1 = posix_time::microsec_clock::local_time();
cout<<endl<<"attempting to lock"<<endl;
cout.flush();
unique_lock<mutex> lock(mut);
posix_time::ptime mst2 = posix_time::microsec_clock::local_time();
posix_time::time_duration msdiff = mst2 - mst1;
cout << std::endl<<"acquired lock in: "<<msdiff.total_milliseconds() << endl;
cout.flush();
}
}
Run Code Online (Sandbox Code Playgroud)
编译: g++ mutextest.cpp -lboost_thread -pthread
当我运行可执行文件时,示例输出如下所示:
...................................................................................................
attempting to …Run Code Online (Sandbox Code Playgroud) 我一直在玩一些GHC扩展来定义一个可以执行以下操作的函数:
let a = A :: A -- Show A
b = B :: B -- Show B
in
myFunc show a b -- This should return (String, String)
Run Code Online (Sandbox Code Playgroud)
myFunc应该在签名中完全多态show,以便它可以接受a并且b满足不同类型Show.
这里是我与GHC扩展的尝试RankNTypes,ConstraintKinds,KindSignatures:
myFunc :: forall (k :: * -> Constraint) a b d. (k a, k b)
=> (forall c. k c => c -> d) -> a -> b -> (d, d)
Run Code Online (Sandbox Code Playgroud)
我的主要目的是了解这些扩展如何工作; 但在我看来,似乎我告诉GHC有k …
我已经在c ++中使用了eigen3线性代数库一段时间了,我一直试图利用矢量化性能优势.今天,我决定测试多少矢量化真正加速我的程序.所以,我写了以下测试程序:
--- eigentest.cpp ---
#include <eigen3/Eigen/Dense>
using namespace Eigen;
#include <iostream>
int main() {
Matrix4d accumulator=Matrix4d::Zero();
Matrix4d randMat = Matrix4d::Random();
Matrix4d constMat = Matrix4d::Constant(2);
for(int i=0; i<1000000; i++) {
randMat+=constMat;
accumulator+=randMat*randMat;
}
std::cout<<accumulator(0,0)<<"\n"; // To avoid optimizing everything away
return 0;
}
Run Code Online (Sandbox Code Playgroud)
然后我用不同的编译器选项编译它后运行这个程序:(结果不是一次性的,很多运行给出类似的结果)
$ g++ eigentest.cpp -o eigentest -DNDEBUG -std=c++0x -march=native
$ time ./eigentest
5.33334e+18
real 0m4.409s
user 0m4.404s
sys 0m0.000s
$ g++ eigentest.cpp -o eigentest -DNDEBUG -std=c++0x
$ time ./eigentest
5.33334e+18
real 0m4.085s
user 0m4.040s
sys 0m0.000s
$ …Run Code Online (Sandbox Code Playgroud) 我正在尝试从C库为"寄存器回调"类型的接口编写一个包装器.这个问题非常复杂,因为库允许您通过接受参数定义列表来注册"可变参数"函数.然后在回调时,该函数应该从类型擦除的参数列表中提取其参数.好老C ...
我正在尝试创建的接口是接受任何函数,甚至是lambda,并自动生成所有机制以正确注册此函数,同时注册参数并在回调时提取它们.因此用户只需键入:
register_callback("Callback Name", [](int i){return i+0.5;});
Run Code Online (Sandbox Code Playgroud)
现在这在理论上是可行的,但是在某一点上,我需要能够在没有任何实例的情况下调用lambda,但只能访问它的类型.我不明白为什么,但是无状态(非捕获)lambda的默认构造函数被删除,所以我不能简单地从它的类型默认构造.我打算做的事情看起来很脏,但应该可以解决这个问题:
template <class Func, class RET, class ...ARGS>
struct from_stateless {
static RET to_function(ARGS...args) {
RET (*f)(ARGS...) = *(Func *)(0);
return f(args...);
}
};
Run Code Online (Sandbox Code Playgroud)
所以这from_stateless<LAMBDA_TYPE, RET, ARGS...>::to_function实际上是一个函数指针,我可以在没有参数的情况下调用,更重要的是我可以作为模板参数传递的函数指针.
在正常情况下,线路RET (*f)(ARGS...) = *(Func *)(0);会自杀,但这个用例确实应该是安全的,不是吗?毕竟,转换后获得的函数指针不能在任何可能依赖于lambda实例的Universe中.
所以,问题是,只要我确保该类型确实是无状态lambda,这样做是否安全?或者我错过了什么?请注意,RET (*f)(ARGS...) = *(Func *)(0);如果闭包意外滑过,则会触发编译器错误.
澄清:我不能将lambda衰减为函数指针并注册它,因为lambda的签名与"Register"方法不兼容.register方法需要一个带签名的函数:void (*)(int number_of_args, TypeErasedValue * arguments, TypeErasedValue * result)所以你看,我需要(并且已经做过),通过模板元编程,生成一个模板化lambda类型的自由函数,作为预期签名和实际签名之间的适配器.
c++ lambda template-meta-programming variadic-templates c++11
c++ ×5
gcc ×2
haskell ×2
lambda ×2
boost ×1
boost-proto ×1
boost-thread ×1
c ×1
c++11 ×1
concurrency ×1
constraints ×1
eigen ×1
java ×1
mutex ×1
nested ×1
performance ×1
polymorphism ×1
swig ×1
syntax ×1
typeclass ×1