Clang访问修饰符顺序和decltype
Clang access modifier order and decltype
我一直在考虑创建一个同步器helper模板类,它是基于Herb Sutter在这次演讲中提出的包装器类的想法。这在msvc中不工作(除非我们删除大括号初始化),但是当大括号初始化被删除时,它就好了。
在clang/gcc (ubuntu 12.10, gcc4.7.2, clang(3.2)用libc++自建)中,似乎私有访问修饰符必须出现在公众之前:这似乎有点奇怪。
gcc中的错误是error: ‘t_’ was not declared in this scope
和clang是
error: use of undeclared identifier 't_'
auto operator()(F f) const ->decltype(f(t_))
这可能是一个模板/declytype问题,我不知道,不知道是否有人可以帮助这一个。(全部使用相关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("Startn");
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_
成为未知专门化的成员
- 对象表达式的类型是依赖的,不是当前实例化的。
第二个是基于使this->t_
成为未知专门化的成员的标准
- 对象表达式的类型是当前实例化,当前实例化至少有一个依赖基类,并且id-表达式的名称查找没有找到当前实例化的成员或其非依赖基类;
这反过来使x->t_
在这两种情况下都是依赖表达式,因此该名称将在实例化时被查找。
类成员访问表达式(5.2.5)是类型依赖的,如果表达式引用当前实例化的成员并且引用的成员的类型是依赖的,或者类成员访问表达式引用未知专门化的成员。
- CMake-按正确顺序将项目与C运行时对象文件链接
- 函数调用中参数的顺序重要吗
- 为什么不;名字在地图上是按顺序排列的吗
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 在VS2010-VS2015下编译时,如何使用decltype作为较大类型表达式的LHS
- 数到第n个楼梯的路(顺序无关紧要)
- 优先顺序:智能指针和类析构函数
- C++decltype和圆括号-为什么
- 在循环中按顺序遍历成员变量
- 独立读取-修改-写入顺序
- 在for循环中使用auto vs decltype(vec.size())来处理字符串的向量
- QML按钮点击功能执行顺序
- 如何从"decltype()"获取函数参数的数量<funtion>?
- Confusion: decltype vs std::function
- C++中数据类型修饰符的顺序
- 当比特(而不是字节)的顺序至关重要时的持久性
- C++从其他 constexpr 创建 lambda 不能按顺序执行 Constexpr
- 通过选项卡的文本设置QTabWidget顺序
- c++11评估顺序(未定义的行为)
- Clang访问修饰符顺序和decltype