Discussion:
C++11: Alias template gives access to private member class template
(too old to reply)
Navyendu VS
2015-01-16 16:34:06 UTC
Permalink
I just happened to find that a nested private template class can be
directly accessed outside the enclosing class using a using directive:


class wrapper
{
private:
template <typename T>
class __tklass {};

class __klass {};
};

template <typename T>
using tklass = wrapper::__tklass<T>; // I was expecting an error here, but this compiles fine

// using klass = wrapper::__klass; // Correctly reports "Error: __klass is private"

int main()
{
tklass<int> v1; // No error here as well

// wrapper::__tklass<int> v3; // Correctly reports "Error: __tklass is private"
// wrapper::__klass v4; // Correctly reports "Error: __klass is private"
}



The lines marked "Error: __xxx is private" correctly report an error when
uncommented. But the lines with tklass get compiled without any complaint
from the compiler. I tried this on gcc-4.9.2, clang-3.5.0 and visual studio
2013 express.

So why exactly doesn't the compiler flag tklass as error despite
wrapper::__tklass being private? If it is indeed allowed by the standard,
why is this exception in access control permitted?


Thanks,

Navyendu VS
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-discussion/.
Gabriel Dos Reis
2015-01-16 17:51:08 UTC
Permalink
Navyendu VS <***@gmail.com> writes:

| I just happened to find that a nested private template class can be
| directly accessed outside the enclosing class using a using directive:
|
|
| class wrapper
| {
| private:
|     template <typename T>
|     class __tklass {};
|    
|     class __klass {};
| };
|
| template <typename T>
| using tklass = wrapper::__tklass<T>;    // I was expecting an error here, but this compiles fine
|
| // using klass = wrapper::__klass;      // Correctly reports "Error: __klass is private"
|
| int main()
| {
|     tklass<int> v1;                     // No error here as well
|
|     // wrapper::__tklass<int> v3;       // Correctly reports "Error: __tklass is private"
|     // wrapper::__klass v4;             // Correctly reports "Error: __klass is private"
| }
|
|
| The lines marked "Error: __xxx is private" correctly report an error
| when uncommented. But the lines with tklass get compiled without any
| complaint from the compiler. I tried this on gcc-4.9.2, clang-3.5.0
| and visual studio 2013 express.
|
| So why exactly doesn't the compiler flag tklass as error despite
| wrapper::__tklass being private? If it is indeed allowed by the
| standard, why is this exception in access control permitted?
|
|
| Thanks,
|
| Navyendu VS

Access checking for template aliases is to be performed just like for
all other templates, in the context of definition. I think there is a
CWG issue for that with that consensus.

-- Gaby
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-discussion/.
Navyendu VS
2015-01-16 18:17:37 UTC
Permalink
Post by Gabriel Dos Reis
| I just happened to find that a nested private template class can be
|
|
| class wrapper
| {
| template <typename T>
| class __tklass {};
|
| class __klass {};
| };
|
| template <typename T>
| using tklass = wrapper::__tklass<T>; // I was expecting an error
here, but this compiles fine
|
__klass is private"
|
| int main()
| {
| tklass<int> v1; // No error here as well
|
__tklass is private"
__klass is private"
| }
|
|
| The lines marked "Error: __xxx is private" correctly report an error
| when uncommented. But the lines with tklass get compiled without any
| complaint from the compiler. I tried this on gcc-4.9.2, clang-3.5.0
| and visual studio 2013 express.
|
| So why exactly doesn't the compiler flag tklass as error despite
| wrapper::__tklass being private? If it is indeed allowed by the
| standard, why is this exception in access control permitted?
|
|
| Thanks,
|
| Navyendu VS
Access checking for template aliases is to be performed just like for
all other templates, in the context of definition. I think there is a
CWG issue for that with that consensus.
-- Gaby
Gabriel, could you please elaborate? I'm an absolute beginner with C++11 ;)

Any pointers to the particular section(s) in the standard would be quite
helpful (plus any additional information on the rationale behind the
consensus).

Thanks,
Navyendu
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-discussion/.
Chris Hallock
2015-01-16 20:10:45 UTC
Permalink
I think he's referring to active core issue #1554
<http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1554>.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-discussion/.
David Krauss
2015-01-17 09:13:55 UTC
Permalink
Post by Gabriel Dos Reis
Access checking for template aliases is to be performed just like for
all other templates, in the context of definition.
In any case, neither the definition nor the point of use has access to the member. No access checking seems to be happening at all.

A few more tests seem to show that you can take any type alias declaration containing illegal access, add template<typename=void> in front, and accomplish the access.
Post by Gabriel Dos Reis
I think there is a
CWG issue for that with that consensus.
It looks like there was consensus in October 2012, but later discussion has entered a grey area.
Post by Gabriel Dos Reis
Concern has been expressed that the intent to analyze access in the context of the alias template definition is at odds with the fact that friendship cannot be granted to alias templates; if it could, the access violation in the original example could be avoided by making foo a friend of class B, but that is not possible.
My 2¢ is that the access violations should be diagnosed, and if users actually complain that they need such friendship, that can be implemented.

In the meantime, that “need” can be mitigated by this workaround:

class needs_alias_friend {
typedef int secret;
friend struct alias_wrapper; // since we can’t friend an alias,
};

struct alias_wrapper { // friend a wrapper,
template< typename t >
using secret_member = typename t::secret; // so this context is OK.
}; // (But see CWG DR 1699.)

template< typename t > // Another alias restores the desired interface.
using secret_member = alias_wrapper::secret_member< t >;
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-discussion/.
Gabriel Dos Reis
2015-01-17 12:33:12 UTC
Permalink
David Krauss <***@gmail.com> writes:

| On 2015–01–17, at 1:51 AM, Gabriel Dos Reis <***@axiomatics.org>
| wrote:
|
|
| Access checking for template aliases is to be performed just like
| for
| all other templates, in the context of definition.  
|
|
| In any case, neither the definition nor the point of use has access to
| the member. No access checking seems to be happening at all.

Like I said, that was intended but not explicitly spelled out. People
(including those in the room) forgot and later got to various
interpretations, far removed from the spirit.

I do have a distinct recollection of the Bristol meeting where CWG was
of the unanimous consent that we needed to open a "meta" issue where we
would just say "template declaration" instead of having to repeat a long
list of all kinds of template declarations, running the risk of
forgetting some and then creating the impression that it was intended to
single one kind out.

-- Gaby
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-discussion/.
Continue reading on narkive:
Loading...