这是我的问题:我想使用gcc或clang提供的C++ 11功能.但是,我有这些要求:
Homebrew似乎只想使用gcc(如果我错了,请纠正我).我找不到任何切换到LLVM的选项.虽然我知道这可能是因为并非所有库都与LLVM兼容,但这仍然是一个很好的功能.
预装在gcc mac上的gcc版本是4.2.gcc 4.2没有所需的c ++ 11功能.我已经安装了通过自制软件4.7,但对于如何设置自制的搜索使用它都说不这样做(GCC 4.2的Mac是不是香草版本,所以在4.7版本我将无法编译一些事情).
我的问题是:有没有人有任何建议或修复他们已经实现解决这个问题?我应该放弃Homebrew吗?有谁知道Homebrew是否有计划在未来转向LLVM?有没有人有如何处理这些不兼容性的升级计划?
从长远来看,我看不出自制软件是如何继续依赖gcc 4.2的,但是没有找到关于此问题的真正讨论.
我的代码遵循以下一般设计:
protocol DispatchType {}
class DispatchType1: DispatchType {}
class DispatchType2: DispatchType {}
func doBar<D:DispatchType>(value:D) {
print("general function called")
}
func doBar(value:DispatchType1) {
print("DispatchType1 called")
}
func doBar(value:DispatchType2) {
print("DispatchType2 called")
}
Run Code Online (Sandbox Code Playgroud)
其中,在现实中DispatchType其实是一个后端存储.这些doBar函数是依赖于正确存储类型的优化方法.如果我这样做,一切正常:
let d1 = DispatchType1()
let d2 = DispatchType2()
doBar(value: d1) // "DispatchType1 called"
doBar(value: d2) // "DispatchType2 called"
Run Code Online (Sandbox Code Playgroud)
但是,如果我创建一个调用的函数doBar:
func test<D:DispatchType>(value:D) {
doBar(value: value)
}
Run Code Online (Sandbox Code Playgroud)
我尝试了类似的呼叫模式,我得到:
test(value: d1) // "general function called"
test(value: d2) // "general function called"
Run Code Online (Sandbox Code Playgroud)
这似乎是Swift应该能够处理的东西,因为它应该能够在编译时确定类型约束.就像快速测试一样,我也试着写作doBar:
func …Run Code Online (Sandbox Code Playgroud) 我正在使用SWIG将c ++类导出到Java,但是在尝试强制代理对象实现接口时遇到了问题.
我搜索了SWIG文档,发现你可以使用"%pragma(java)jniclassinterfaces = x"让JNI类实现给定的接口,并使用"%pragma(java)moduleinterfaces = x"让模块实现任何给定的接口,但实际代理对象没有相应的编译指示.
我希望让SWIG生成'implements X'代码,因为稍后尝试添加该实现是很困难的.例如,如果我尝试子类化SWIG代理然后实现接口,我会遇到问题,因为我也使用泛型:
interface IVector<VectorType> {
VectorType add(VectorType other);
...
}
Run Code Online (Sandbox Code Playgroud)
所以这样的事情失败了:
class MyVector extends MyProxyVector implements IVector<MyVector> {
MyVector add(MyVector other) {
return (MyVector) super.add(other);
}
}
Run Code Online (Sandbox Code Playgroud)
因为它需要将父类转换为子类.
我能解决这个问题的唯一方法是创建一个包装类或使用一个复制构造函数.两者似乎都有点低效,因为它们实现了一个接口的全部目的.
我正在尝试构建一个需要由一个线程执行的函数的工作队列,并且可以由许多线程提供.为实现这一目标,我计划使用boost :: packaged_task和boost :: unique_future.这个想法是你会做的:
Foo value = queue.add(myFunc).get();
哪个会阻塞,直到执行该功能.所以queue.add(...)接受一个boost :: function,并返回一个boost :: unique_future.在内部,它然后使用boost :: function为其构造函数创建一个boost :: packaged_task.
我遇到的问题是boost :: function <...>每次都不一样.具体来说,它的返回值将会改变(但是,函数永远不会采用任何参数).因此,我必须有一个类似于以下内容的add函数:
template <typename ResultType>
boost::unique_future<ResultType> add(boost::function<ResultType ()> f) {
boost::packaged_task<boost::function<ResultType ()> > task(f);
queue.push_back(task);
return task.get_future();
}
Run Code Online (Sandbox Code Playgroud)
好吧,这似乎并不太糟糕,但后来我遇到了如何定义'队列'的问题.我想我别无选择,只能使用boost :: any,因为类型不会是常量:
std::list<boost::any> queue; // note: I'm not concerned with thread-safety yet
Run Code Online (Sandbox Code Playgroud)
但是当我尝试实现我的executeSingle时,我遇到了一个问题(只从队列中取出一个项目来执行):
void executeSingle() {
boost::any value = queue.back();
boost::packaged_task<?> task = boost::packaged_task<?>(boost::move(value));
// actually execute task
task();
queue.pop_back();
}
Run Code Online (Sandbox Code Playgroud)
'?' 表示我不确定的事情.我不能用模板调用executeSingle,因为它是从一个单独的线程调用的.我尝试使用boost :: any,但是我得到了错误:
conversion from 'boost::any' to non-scalar type …Run Code Online (Sandbox Code Playgroud) 我正在使用IPython.parallel来处理集群上的大量数据.我运行的远程功能如下:
def evalPoint(point, theta):
# do some complex calculation
return (cost, grad)
Run Code Online (Sandbox Code Playgroud)
这个函数调用它:
def eval(theta, client, lview, data):
async_results = []
for point in data:
# evaluate current data point
ar = lview.apply_async(evalPoint, point, theta)
async_results.append(ar)
# wait for all results to come back
client.wait(async_results)
# and retrieve their values
values = [ar.get() for ar in async_results]
# unzip data from original tuple
totalCost, totalGrad = zip(*values)
avgGrad = np.mean(totalGrad, axis=0)
avgCost = np.mean(totalCost, axis=0)
return (avgCost, avgGrad)
Run Code Online (Sandbox Code Playgroud)
如果我运行代码:
client …Run Code Online (Sandbox Code Playgroud) 我遇到了来自clang ++编译器的sizeof ...()运算符的奇怪行为:
template <typename... Args>
void test(tuple<Args...> t) {
cout << "size: " << sizeof...(Args) << endl;
}
...
test(make_tuple(1, 2)); // prints 'size: 10'
Run Code Online (Sandbox Code Playgroud)
我意识到更标准的方法是:
template <typename... Args>
void test(tuple<Args...> t) {
cout << "size: " << tuple_size<tuple<Args...> >::value << endl;
}
test(make_tuple(1, 2)); // prints 'size: 2'
Run Code Online (Sandbox Code Playgroud)
但我仍然很好奇为什么我得到第一个版本的奇怪值.对于这种情况,sizeof ...()的值是不定义的,还是编译器行为不端?
我需要检查给定的类是否<<(cls, ostream)定义了运算符.如果是这样,我希望我的函数使用它来写入ostringstream,否则应该使用样板代码.
我知道之前已经问过这个问题.但是,我通常会发现自定义解决方案并不总是适用于我的编译器(clang ++).经过几个小时的搜索,我终于发现了boost :: type_traits.我之前没有看过那里,因为我假设c ++ 11已经复制了特征部门的所有内容.
对我有用的解决方案是:
template <typename C>
std::string toString(C &instance) {
std::ostringstream out;
out << to_string<C, boost::has_left_shift<C, std::ostream>::value>::convert(ctx);
return out.str();
}
Run Code Online (Sandbox Code Playgroud)
以to_string定义为:
template <typename C, bool>
struct to_string {
// will never get called
static std::string convert(LuaContext &ctx) {}
};
template <typename C>
struct to_string<C, true> {
static std::string convert(LuaContext &ctx) {
return "convert(true) called.";
}
};
template <typename C>
struct to_string<C, false> {
static std::string convert(LuaContext &ctx) { …Run Code Online (Sandbox Code Playgroud) 对于我的项目(编译为框架),我有一个文件ops.metal:
kernel void add(device float *lhs [[buffer(0)]],
device float *rhs [[buffer(1)]],
device float *result [[buffer(2)]],
uint id [[ thread_position_in_grid ]])
{
result[id] = lhs[id] + rhs[id];
}
Run Code Online (Sandbox Code Playgroud)
以及以下Swift代码:
@available(OSX 10.11, *)
public class MTLContext {
var device: MTLDevice!
var commandQueue:MTLCommandQueue!
var library:MTLLibrary!
var commandBuffer:MTLCommandBuffer
var commandEncoder:MTLComputeCommandEncoder
init() {
if let defaultDevice = MTLCreateSystemDefaultDevice() {
device = defaultDevice
print("device created")
} else {
print("Metal is not supported")
}
commandQueue = device.makeCommandQueue()
library = device.newDefaultLibrary()
if let defaultLibrary = device.newDefaultLibrary() …Run Code Online (Sandbox Code Playgroud) 我很确定这是危险的代码.但是,我想检查是否有人知道究竟会出现什么问题.
假设我有这个类结构:
class A {
protected:
int a;
public:
A() { a = 0; }
int getA() { return a; }
void setA(int v) { a = v; }
};
class B: public A {
protected:
int b;
public:
B() { b = 0; }
};
Run Code Online (Sandbox Code Playgroud)
然后假设我想要一种自动扩展类的方法,如下所示:
class Base {
public:
virtual ~Base() {}
};
template <typename T>
class Test: public T, public Base {};
Run Code Online (Sandbox Code Playgroud)
我能做出的一个非常重要的保证是既Base不会也不Test会有任何其他成员变量或方法.它们本质上是空类.
(可能)危险的代码如下:
int main() { …Run Code Online (Sandbox Code Playgroud) c++ ×5
c++11 ×2
swift ×2
boost ×1
dispatch ×1
dynamic-cast ×1
gcc ×1
generics ×1
homebrew ×1
inheritance ×1
interface ×1
ipython ×1
java ×1
llvm ×1
memory-leaks ×1
metal ×1
operators ×1
overriding ×1
polymorphism ×1
proxy ×1
queue ×1
shader ×1
sizeof ×1
static-cast ×1
swig ×1
templates ×1
type-traits ×1