Access control in template parametersIs it really a good technique to work with legacy code (with...
How to use Mathematica to do a complex integrate with poles in real axis?
Is it possible to grant users sftp access without shell access? If yes, how is it implemented?
Am I a Rude Number?
Why is working on the same position for more than 15 years not a red flag?
Do authors have to be politically correct in article-writing?
How does Leonard in "Memento" remember reading and writing?
How would an AI self awareness kill switch work?
How do you funnel food off a cutting board?
Why do neural networks need so many training examples to perform?
Why publish a research paper when a blog post or a lecture slide can have more citation count than a journal paper?
Can we harness gravitational potential energy?
A Missing Symbol for This Logo
Early credit roll before the end of the film
Odd 74HCT1G125 behaviour
Why did Democrats in the Senate oppose the Born-Alive Abortion Survivors Protection Act (2019 S.130)?
Cat is tipping over bed-side lamps during the night
False written accusations not made public - is there law to cover this?
What does it mean for a caliber to be flat shooting?
What sets the resolution of an analog resistive sensor?
A starship is travelling at 0.9c and collides with a small rock. Will it leave a clean hole through, or will more happen?
How can I play a serial killer in a party of good PCs?
Why exactly do action photographers need high fps burst cameras?
What's a good word to describe a public place that looks like it wouldn't be rough?
Cookies - Should the toggles be on?
Access control in template parameters
Is it really a good technique to work with legacy code (with reinterpret_cast)?Use 'class' or 'typename' for template parameters?Why can templates only be implemented in the header file?Where and why do I have to put the “template” and “typename” keywords?Can a local variable's memory be accessed outside its scope?Are the days of passing const std::string & as a parameter over?Why can't new template parameters be introduced in full specializations?A failure to instantiate function templates due to universal (forward) reference to a templated typeWhy give a typename template parameter a default value of 0 in C++?Using Template in struct in C++Error in template instantiation before overloading
Inspired from this answer, which claims to subvert the access control system, I wrote the following minimal version of the hack
template<typename T>
inline T memptr{};
template<auto Val>
struct setptr
{
struct setter { setter() { memptr<decltype(Val)> = Val; } };
static setter s;
};
template<auto Val>
typename setptr<Val>::setter setptr<Val>::s{};
which is then used as
class S
{
int i;
};
template struct setptr<&S::i>;
auto no_privacy(S& s)
{
return s.*memptr<int S::*>;
}
Why doesn't template struct setptr<&S::i>;
violate access control?
Is it because [class.access]
Access control is applied uniformly to all names, whether the names are referred to from declarations or expressions.
specifically doesn't include instantiations? In which case, why doesn't it include instantiations?
Errata: Explicit instantiations are also classified as declarations.
c++ language-lawyer
|
show 3 more comments
Inspired from this answer, which claims to subvert the access control system, I wrote the following minimal version of the hack
template<typename T>
inline T memptr{};
template<auto Val>
struct setptr
{
struct setter { setter() { memptr<decltype(Val)> = Val; } };
static setter s;
};
template<auto Val>
typename setptr<Val>::setter setptr<Val>::s{};
which is then used as
class S
{
int i;
};
template struct setptr<&S::i>;
auto no_privacy(S& s)
{
return s.*memptr<int S::*>;
}
Why doesn't template struct setptr<&S::i>;
violate access control?
Is it because [class.access]
Access control is applied uniformly to all names, whether the names are referred to from declarations or expressions.
specifically doesn't include instantiations? In which case, why doesn't it include instantiations?
Errata: Explicit instantiations are also classified as declarations.
c++ language-lawyer
See also gotw.ca/gotw/076.htm
– Jesper Juhl
4 hours ago
We actually use this "hack" in one place in our code base to be able to call a private member function in a library that we really need to call ;-) But, I suspect it could also be useful in test frameworks where you may want to test protected and private members without having to inject friends and other stuff.
– Jesper Juhl
4 hours ago
If you follow a few links from the answer, you get to this commented version, where it is elaborated that explicit instantiations are the only place where you can form member function/field pointers while ignoring access. There is even more explanation in this library linked in the comments to an answer in the question you linked.
– Max Langhof
4 hours ago
@MaxLanghof I actually saw those, but couldn't find the source of their claims.
– Passer By
4 hours ago
We used to use this to workaround buggystd::fstream
implementation in older visual studio version by accessing the underlyingFILE
handle
– Alan Birtles
4 hours ago
|
show 3 more comments
Inspired from this answer, which claims to subvert the access control system, I wrote the following minimal version of the hack
template<typename T>
inline T memptr{};
template<auto Val>
struct setptr
{
struct setter { setter() { memptr<decltype(Val)> = Val; } };
static setter s;
};
template<auto Val>
typename setptr<Val>::setter setptr<Val>::s{};
which is then used as
class S
{
int i;
};
template struct setptr<&S::i>;
auto no_privacy(S& s)
{
return s.*memptr<int S::*>;
}
Why doesn't template struct setptr<&S::i>;
violate access control?
Is it because [class.access]
Access control is applied uniformly to all names, whether the names are referred to from declarations or expressions.
specifically doesn't include instantiations? In which case, why doesn't it include instantiations?
Errata: Explicit instantiations are also classified as declarations.
c++ language-lawyer
Inspired from this answer, which claims to subvert the access control system, I wrote the following minimal version of the hack
template<typename T>
inline T memptr{};
template<auto Val>
struct setptr
{
struct setter { setter() { memptr<decltype(Val)> = Val; } };
static setter s;
};
template<auto Val>
typename setptr<Val>::setter setptr<Val>::s{};
which is then used as
class S
{
int i;
};
template struct setptr<&S::i>;
auto no_privacy(S& s)
{
return s.*memptr<int S::*>;
}
Why doesn't template struct setptr<&S::i>;
violate access control?
Is it because [class.access]
Access control is applied uniformly to all names, whether the names are referred to from declarations or expressions.
specifically doesn't include instantiations? In which case, why doesn't it include instantiations?
Errata: Explicit instantiations are also classified as declarations.
c++ language-lawyer
c++ language-lawyer
edited 3 hours ago
Passer By
asked 4 hours ago
Passer ByPasser By
9,92432558
9,92432558
See also gotw.ca/gotw/076.htm
– Jesper Juhl
4 hours ago
We actually use this "hack" in one place in our code base to be able to call a private member function in a library that we really need to call ;-) But, I suspect it could also be useful in test frameworks where you may want to test protected and private members without having to inject friends and other stuff.
– Jesper Juhl
4 hours ago
If you follow a few links from the answer, you get to this commented version, where it is elaborated that explicit instantiations are the only place where you can form member function/field pointers while ignoring access. There is even more explanation in this library linked in the comments to an answer in the question you linked.
– Max Langhof
4 hours ago
@MaxLanghof I actually saw those, but couldn't find the source of their claims.
– Passer By
4 hours ago
We used to use this to workaround buggystd::fstream
implementation in older visual studio version by accessing the underlyingFILE
handle
– Alan Birtles
4 hours ago
|
show 3 more comments
See also gotw.ca/gotw/076.htm
– Jesper Juhl
4 hours ago
We actually use this "hack" in one place in our code base to be able to call a private member function in a library that we really need to call ;-) But, I suspect it could also be useful in test frameworks where you may want to test protected and private members without having to inject friends and other stuff.
– Jesper Juhl
4 hours ago
If you follow a few links from the answer, you get to this commented version, where it is elaborated that explicit instantiations are the only place where you can form member function/field pointers while ignoring access. There is even more explanation in this library linked in the comments to an answer in the question you linked.
– Max Langhof
4 hours ago
@MaxLanghof I actually saw those, but couldn't find the source of their claims.
– Passer By
4 hours ago
We used to use this to workaround buggystd::fstream
implementation in older visual studio version by accessing the underlyingFILE
handle
– Alan Birtles
4 hours ago
See also gotw.ca/gotw/076.htm
– Jesper Juhl
4 hours ago
See also gotw.ca/gotw/076.htm
– Jesper Juhl
4 hours ago
We actually use this "hack" in one place in our code base to be able to call a private member function in a library that we really need to call ;-) But, I suspect it could also be useful in test frameworks where you may want to test protected and private members without having to inject friends and other stuff.
– Jesper Juhl
4 hours ago
We actually use this "hack" in one place in our code base to be able to call a private member function in a library that we really need to call ;-) But, I suspect it could also be useful in test frameworks where you may want to test protected and private members without having to inject friends and other stuff.
– Jesper Juhl
4 hours ago
If you follow a few links from the answer, you get to this commented version, where it is elaborated that explicit instantiations are the only place where you can form member function/field pointers while ignoring access. There is even more explanation in this library linked in the comments to an answer in the question you linked.
– Max Langhof
4 hours ago
If you follow a few links from the answer, you get to this commented version, where it is elaborated that explicit instantiations are the only place where you can form member function/field pointers while ignoring access. There is even more explanation in this library linked in the comments to an answer in the question you linked.
– Max Langhof
4 hours ago
@MaxLanghof I actually saw those, but couldn't find the source of their claims.
– Passer By
4 hours ago
@MaxLanghof I actually saw those, but couldn't find the source of their claims.
– Passer By
4 hours ago
We used to use this to workaround buggy
std::fstream
implementation in older visual studio version by accessing the underlying FILE
handle– Alan Birtles
4 hours ago
We used to use this to workaround buggy
std::fstream
implementation in older visual studio version by accessing the underlying FILE
handle– Alan Birtles
4 hours ago
|
show 3 more comments
1 Answer
1
active
oldest
votes
From [temp.spec]/6 (emphasis mine):
The usual access checking rules do not apply to names in a declaration of an explicit instantiation or explicit specialization, with the exception of names appearing in a function body, default argument, base-clause, member-specification, enumerator-list, or static data member or variable template initializer.
[ Note: In particular, the template arguments and names used in the function declarator (including parameter types, return types and exception specifications) may be private types or objects that would normally not be accessible.
— end note
]
So this technique you see abuses this rule, which is primarely there to allow implementers of a class specialize templates (such as traits) with private types or other private entities
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54909496%2faccess-control-in-template-parameters%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
From [temp.spec]/6 (emphasis mine):
The usual access checking rules do not apply to names in a declaration of an explicit instantiation or explicit specialization, with the exception of names appearing in a function body, default argument, base-clause, member-specification, enumerator-list, or static data member or variable template initializer.
[ Note: In particular, the template arguments and names used in the function declarator (including parameter types, return types and exception specifications) may be private types or objects that would normally not be accessible.
— end note
]
So this technique you see abuses this rule, which is primarely there to allow implementers of a class specialize templates (such as traits) with private types or other private entities
add a comment |
From [temp.spec]/6 (emphasis mine):
The usual access checking rules do not apply to names in a declaration of an explicit instantiation or explicit specialization, with the exception of names appearing in a function body, default argument, base-clause, member-specification, enumerator-list, or static data member or variable template initializer.
[ Note: In particular, the template arguments and names used in the function declarator (including parameter types, return types and exception specifications) may be private types or objects that would normally not be accessible.
— end note
]
So this technique you see abuses this rule, which is primarely there to allow implementers of a class specialize templates (such as traits) with private types or other private entities
add a comment |
From [temp.spec]/6 (emphasis mine):
The usual access checking rules do not apply to names in a declaration of an explicit instantiation or explicit specialization, with the exception of names appearing in a function body, default argument, base-clause, member-specification, enumerator-list, or static data member or variable template initializer.
[ Note: In particular, the template arguments and names used in the function declarator (including parameter types, return types and exception specifications) may be private types or objects that would normally not be accessible.
— end note
]
So this technique you see abuses this rule, which is primarely there to allow implementers of a class specialize templates (such as traits) with private types or other private entities
From [temp.spec]/6 (emphasis mine):
The usual access checking rules do not apply to names in a declaration of an explicit instantiation or explicit specialization, with the exception of names appearing in a function body, default argument, base-clause, member-specification, enumerator-list, or static data member or variable template initializer.
[ Note: In particular, the template arguments and names used in the function declarator (including parameter types, return types and exception specifications) may be private types or objects that would normally not be accessible.
— end note
]
So this technique you see abuses this rule, which is primarely there to allow implementers of a class specialize templates (such as traits) with private types or other private entities
edited 4 hours ago
answered 4 hours ago
Guillaume RacicotGuillaume Racicot
14.5k53467
14.5k53467
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54909496%2faccess-control-in-template-parameters%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
See also gotw.ca/gotw/076.htm
– Jesper Juhl
4 hours ago
We actually use this "hack" in one place in our code base to be able to call a private member function in a library that we really need to call ;-) But, I suspect it could also be useful in test frameworks where you may want to test protected and private members without having to inject friends and other stuff.
– Jesper Juhl
4 hours ago
If you follow a few links from the answer, you get to this commented version, where it is elaborated that explicit instantiations are the only place where you can form member function/field pointers while ignoring access. There is even more explanation in this library linked in the comments to an answer in the question you linked.
– Max Langhof
4 hours ago
@MaxLanghof I actually saw those, but couldn't find the source of their claims.
– Passer By
4 hours ago
We used to use this to workaround buggy
std::fstream
implementation in older visual studio version by accessing the underlyingFILE
handle– Alan Birtles
4 hours ago