我一直在考虑创建一个同步器助手模板类,它基于 Herb Sutter 在这个 talk 中的包装器类的想法。这在 msvc 中不起作用(除非我们删除大括号初始化)但是当大括号初始化被删除时就没问题了。
在 clang/gcc (ubuntu 12.10, gcc4.7.2, clang (3.2) self built with libc++) 中,private 访问修饰符似乎必须出现在 public 之前:这看起来有点奇怪。
gcc 的错误是
错误:“t_”未在此范围内声明
clang 是
error: use of undeclared identifier 't_'
auto operator()(F f) const ->decltype(f(t_))
这可能是一个我不知道的模板/declytpe 问题,想知道是否有人可以帮助解决这个问题。 (全部使用相关的 c++11 标志编译)
template <class T>
class Synchronised {
public:
Synchronised(T t = T{}) : t_{t} {}
template <typename F>
auto operator()(F f) const -> decltype(f(t_)) {
std::lock_guard<std::mutex> lock{mutex_};
return f(t_);
}
private: // place this before public: and this object compiles
mutable T t_;
mutable std::mutex mutex_;
};
编辑:添加 Johannes 的想法和全类,以防有人需要剪切和粘贴。
#include <future>
#include <iostream>
#include <thread>
#include <vector>
template <class T> T &self(T &t) { return t; }
template<typename T> struct Dependent { };
template<typename T>
class Synchronised : Dependent<T>{
public:
explicit Synchronised(T t = T()) : t_(t) {}
template<typename Functor>
auto operator()(Functor functor) const ->decltype(functor(self(*this).t_)) {
//auto operator()(Functor functor) const ->decltype(functor(this->t_)) {
std::lock_guard<std::mutex> lock(mutex_);
return functor(t_);
}
private:
mutable T t_;
mutable std::mutex mutex_;
};
int main() {
Synchronised<std::string> sync_string("Start\n");
std::vector<std::future<void>> futures;
}
最佳答案
以下仅足以使类模板定义本身有效。然而,同样的规则使得查找在类模板中找不到数据成员(这需要引入空的依赖基类或依赖函数调用)也会使类模板的实例化找不到数据成员,并且因此将触发编译器错误。
我们告诉编译器“等一下,也许你会在实例化时找到数据成员”,但我没有考虑实际实例化时会发生什么。我们现在要做到这一点,即使在类实例化发生后,名称仍然是依赖的。解析必须等到调用 operator()。
// keep this little util somewhere :)
template<typename T>
struct self {
template<typename U> U &operator()(U &t) { return t; }
};
template <class T>
class Synchronised {
public:
// ...
auto operator()(F f) const -> decltype(f(self<F>()(*this).t_)) {
// ...
};
self 使用类模板而不是函数模板也将防止参数依赖查找的发生,防止 F 的作者也编写了一个名为self 与参数 *this 匹配(这也可能是下面部分解决方案的潜在问题)。
除了重新排序,你还有其他几个选择
使 . 左侧的表达式依赖,但不仅仅是封闭类(因为它将是特殊情况)
// keep this little util somewhere :)
template <class T> T &self(T &t) { return t; }
template <class T>
class Synchronised {
public:
// ...
auto operator()(F f) const -> decltype(f(self(*this).t_)) {
// ...
};
引入一个依赖基类来解决封闭类的特殊情况
// Keep this little util somewhere
template<typename T> struct Dependent { };
template <class T>
class Synchronised : Dependent<T> {
public:
// ...
auto operator()(F f) const -> decltype(f(this->t_)) {
// ...
};
第一个是基于使 self(*this).t_ 成为未知特化成员的标准
- the type of the object expression is dependent and is not the current instantiation.
第二个基于使 this->t_ 成为未知特化成员的标准
- the type of the object expression is the current instantiation, the current instantiation has at least one dependent base class, and name lookup of the id-expression does not find a member of the current instantiation or a non-dependent base class thereof;
这反过来使 x->t_ 对于这两种情况都是依赖表达式,因此将在实例化时查找名称。标准说
A class member access expression (5.2.5) is type-dependent if the expression refers to a member of the current instantiation and the type of the referenced member is dependent, or the class member access expression refers to a member of an unknown specialization.
关于c++ - Clang 访问修饰符顺序和 decltype,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14188535/
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以
我遵循了教程http://gettingstartedwithchef.com/,第1章。我的运行list是"run_list":["recipe[apt]","recipe[phpap]"]我的phpapRecipe默认Recipeinclude_recipe"apache2"include_recipe"build-essential"include_recipe"openssl"include_recipe"mysql::client"include_recipe"mysql::server"include_recipe"php"include_recipe"php::modul
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
RSpec似乎按顺序匹配方法接收的消息。我不确定如何使以下代码工作:allow(a).toreceive(:f)expect(a).toreceive(:f).with(2)a.f(1)a.f(2)a.f(3)我问的原因是a.f的一些调用是由我的代码的上层控制的,所以我不能对这些方法调用添加期望。 最佳答案 RSpecspy是测试这种情况的一种方式。要监视一个方法,用allowstub,除了方法名称之外没有任何约束,调用该方法,然后expect确切的方法调用。例如:allow(a).toreceive(:f)a.f(2)a.f(1)
我想从then子句中访问case语句表达式,即food="cheese"casefoodwhen"dip"then"carrotsticks"when"cheese"then"#{expr}crackers"else"mayo"end在这种情况下,expr是食物的当前值(value)。在这种情况下,我知道,我可以简单地访问变量food,但是在某些情况下,该值可能无法再访问(array.shift等)。除了将expr移出到局部变量然后访问它之外,是否有直接访问caseexpr值的方法?罗亚附注我知道这个具体示例很简单,只是一个示例场景。 最佳答案
我理解(我认为)Ruby中类变量和类的实例变量之间的区别。我想知道如何从该类外部访问该类的实例变量。从内部(即在类方法中而不是实例方法中),它可以直接访问,但是从外部,有没有办法做MyClass.class.[@$#]variablename?我没有任何具体原因要这样做,只是学习Ruby并想知道是否可行。 最佳答案 classMyClass@my_class_instance_var="foo"class上述yield:>>foo我相信Arkku演示了如何从类外部访问类变量(@@),而不是类实例变量(@)。我从这篇文章中提取了上述内