[cfe-dev] Possible bug with decltype and access modifer order

Richard Smith richard at metafoo.co.uk
Mon Jan 14 13:52:11 PST 2013


On Mon, Jan 14, 2013 at 1:01 PM, David Irvine <david.irvine at maidsafe.net>wrote:

> Please see this stackoverflow question for an overview.
> http://stackoverflow.com/questions/14188535/clang-access-modifier-order-and-decltype
>
> The issue seems to be that the private members are not visible at
> compilation to the decltype call. This is a minimum example (from the
> question).  (I am the questioner in this case). This also seems to appear
> as a 'bug' in gcc but not msvc (12). I am not
> 100% convinced but cannot find in the standard why this will not work. I
> hope this helps.
>
> #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;}
>
>
> Best Regards
> David Irvine
>
>
>  <http://maidsafe.net>maidsafe.net Limited is a limited liability company
> incorporated in Scotland with number SC297540. VAT Registered 889 0608 77.
> Registered Office: 72 Templehill, Troon, KA10 6BE.
> Telephone Scotland: +44 1292 750020.
>
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>
>
The instantiation of the template looks like this:

template<> class Synchronised<std::string> : Dependent<std::string> { public
: explicit Synchronised(std::string t = std::string()) : t_(t) {} template<
typename Functor> auto operator()(Functor functor) const ->decltype(functor(
self(*this).t_)) { std::lock_guard<std::mutex> lock(mutex_); return functor(
t_); } private: mutable std::string t_; mutable std::mutex mutex_; };

This is ill-formed, since t_ has not yet been declared when the
trailing-return-type for operator() is processed. Per
[basic.lookup.classref]p2, the name t_ is looked up in the scope of class
Synchronized<std::string>. Per [basic.scope.class]p1, the name is not in
scope in the trailing-return-type, because it is not in the declarative
region following the name's point of declaration, and isn't a function
body, default argument, nor non-static data member initializer.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20130114/fc394862/attachment.html>


More information about the cfe-dev mailing list