【发布时间】:2013-01-07 01:03:57
【问题描述】:
我一直在考虑创建一个同步器帮助器模板类,它基于 Herb Sutter 在这个 talk 中的包装器类的想法这在 msvc 中不起作用(除非我们删除大括号初始化)但是当大括号初始化时被删除然后没关系。
在 clang/gcc (ubuntu 12.10, gcc4.7.2, clang (3.2) selfbuilt with libc++) 中,似乎私有访问修饰符必须出现在公众面前:这似乎有点奇怪。
gcc 中的错误是
error: ‘t_’ was not declared in this scope
而铿锵声是
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;
}
【问题讨论】:
-
向霍华德道歉,我现在已将正确答案移至约翰内斯版本。使用 clang 3.2 实际上它确实在这方面出错,所以现在看来它不是未定义的行为,我认为这是个好消息。
-
确诊不代表不是UB
-
@Johannes 正确但不编译是一个好兆头,或者至少在正确的方向上)
标签: c++ templates c++11 dependent-name