C++ standard requirements to templates that are not instantiated
So I tried to compile the code below and it failed (as expected):
1.cpp: In function ‘int foo()’:
1.cpp:3:5: error: ‘some’ was not declared in this scope
some ill-formed code
^
But if I remove this line the compiler compiles it without any errors (also expected as it is unknown whether the T
type has random_name()
method or not).
It seems that diagnostic for templates that are not used (not instantiated) is implementation defined to some extent. But perhaps the standard has some requirements for such cases. For example would it conform to the standard to compile the code below without any errors?
I tried to search for the answer on the site but could not find any related questions.
template <class T>
int foo() {
some ill-formed code
return T::random_name();
}
template <>
int foo<int>() { return 0; }
int main() {
return foo<int>();
}
c++ templates template-instantiation
add a comment |
So I tried to compile the code below and it failed (as expected):
1.cpp: In function ‘int foo()’:
1.cpp:3:5: error: ‘some’ was not declared in this scope
some ill-formed code
^
But if I remove this line the compiler compiles it without any errors (also expected as it is unknown whether the T
type has random_name()
method or not).
It seems that diagnostic for templates that are not used (not instantiated) is implementation defined to some extent. But perhaps the standard has some requirements for such cases. For example would it conform to the standard to compile the code below without any errors?
I tried to search for the answer on the site but could not find any related questions.
template <class T>
int foo() {
some ill-formed code
return T::random_name();
}
template <>
int foo<int>() { return 0; }
int main() {
return foo<int>();
}
c++ templates template-instantiation
add a comment |
So I tried to compile the code below and it failed (as expected):
1.cpp: In function ‘int foo()’:
1.cpp:3:5: error: ‘some’ was not declared in this scope
some ill-formed code
^
But if I remove this line the compiler compiles it without any errors (also expected as it is unknown whether the T
type has random_name()
method or not).
It seems that diagnostic for templates that are not used (not instantiated) is implementation defined to some extent. But perhaps the standard has some requirements for such cases. For example would it conform to the standard to compile the code below without any errors?
I tried to search for the answer on the site but could not find any related questions.
template <class T>
int foo() {
some ill-formed code
return T::random_name();
}
template <>
int foo<int>() { return 0; }
int main() {
return foo<int>();
}
c++ templates template-instantiation
So I tried to compile the code below and it failed (as expected):
1.cpp: In function ‘int foo()’:
1.cpp:3:5: error: ‘some’ was not declared in this scope
some ill-formed code
^
But if I remove this line the compiler compiles it without any errors (also expected as it is unknown whether the T
type has random_name()
method or not).
It seems that diagnostic for templates that are not used (not instantiated) is implementation defined to some extent. But perhaps the standard has some requirements for such cases. For example would it conform to the standard to compile the code below without any errors?
I tried to search for the answer on the site but could not find any related questions.
template <class T>
int foo() {
some ill-formed code
return T::random_name();
}
template <>
int foo<int>() { return 0; }
int main() {
return foo<int>();
}
c++ templates template-instantiation
c++ templates template-instantiation
asked Nov 26 '18 at 2:09
eXXXXXXXXXXX2eXXXXXXXXXXX2
71511227
71511227
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
This is a quality of implementation issue, it is ill-formed but if it is not instantiated no diagnostic is required as per [temp.res#8.1]p:
The validity of a template may be checked prior to any instantiation.
[ Note: Knowing which names are type names allows the syntax of every template to be checked in this way.
— end note
]
The program is ill-formed, no diagnostic required, if:
- no valid specialization can be generated for a template or a substatement of a constexpr if statement within a template and the template is not instantiated, or
and we can see from this live godbolt example MSVC does not diagnose this case. This is because MSVC is not using two-phase lookup but using /permissive-
changes this. clang even has an MSVC compatibility mode to emulate this using -fdelayed-template-parsing
.
We can see from this live godbolt using these two options clang no longer produces a diagnostic but MSVC does.
That rule is quite confusing.template<class T> SomeParticularError { static_assert(always_false<T>::value); };
is very common, but this rule seems to apply. That is, ifSomeParticularError
is not actually instantiated, this is ill-formed, NDR.
– llllllllll
Nov 26 '18 at 2:50
@liliscent - That rule doesn't apply.alwsys_false
may still have a specialization producing a true value. It's a non-deduced context for a reason.
– StoryTeller
Nov 26 '18 at 5:00
@StoryTeller If this is true, then the "and the template is not instantiated" part seems to be redundant, since a template will never be instantiated at its definition. In my previous comment, I thought that sentence means "it's not instantiated during the whole translation unit", if it refers to the whole TU, compiler has all the knowledge to determine whether there are other specializations ofalways_false
.
– llllllllll
Nov 26 '18 at 6:12
@liliscent - It's not redundant. The point here is that one can tell the construct is ill-formed without instantiating the template. But withalways_false
one can never tell a specialization won't exist.
– StoryTeller
Nov 26 '18 at 6:14
@StoryTeller I believe you're right. I was just thinking the wording could've been more clear, since the whole section [temp.res]/8 is talking about ill-formedness at a template's definition, not instantiated is implied from the context of that section.
– llllllllll
Nov 26 '18 at 6:25
add a comment |
Names inside a function template
are either dependent, i.e., the entity depends on the template
parameters in some form, or they are independent, i.e., there is no indication that it depends on a template
parameter. Independent names are looked up when the function template
is defined. Dependent names are looked up during template
instantiation, i.e., at the name doesn’t need to be defined when the function template
is defined. Failure to look-up a name is an error. The details of this process are a bit more involved and fill most of the chapter on template
s.
In your case some
is an independent name while the T::
qualification makes random_name
a dependent name.
some ill-formed
is a syntax error though, so I don't think it gets so far as dependent name analysis
– M.M
Nov 26 '18 at 2:51
@M.M.: the error message implies it tried to locate the name...
– Dietmar Kühl
Nov 26 '18 at 3:01
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%2f53473934%2fc-standard-requirements-to-templates-that-are-not-instantiated%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
This is a quality of implementation issue, it is ill-formed but if it is not instantiated no diagnostic is required as per [temp.res#8.1]p:
The validity of a template may be checked prior to any instantiation.
[ Note: Knowing which names are type names allows the syntax of every template to be checked in this way.
— end note
]
The program is ill-formed, no diagnostic required, if:
- no valid specialization can be generated for a template or a substatement of a constexpr if statement within a template and the template is not instantiated, or
and we can see from this live godbolt example MSVC does not diagnose this case. This is because MSVC is not using two-phase lookup but using /permissive-
changes this. clang even has an MSVC compatibility mode to emulate this using -fdelayed-template-parsing
.
We can see from this live godbolt using these two options clang no longer produces a diagnostic but MSVC does.
That rule is quite confusing.template<class T> SomeParticularError { static_assert(always_false<T>::value); };
is very common, but this rule seems to apply. That is, ifSomeParticularError
is not actually instantiated, this is ill-formed, NDR.
– llllllllll
Nov 26 '18 at 2:50
@liliscent - That rule doesn't apply.alwsys_false
may still have a specialization producing a true value. It's a non-deduced context for a reason.
– StoryTeller
Nov 26 '18 at 5:00
@StoryTeller If this is true, then the "and the template is not instantiated" part seems to be redundant, since a template will never be instantiated at its definition. In my previous comment, I thought that sentence means "it's not instantiated during the whole translation unit", if it refers to the whole TU, compiler has all the knowledge to determine whether there are other specializations ofalways_false
.
– llllllllll
Nov 26 '18 at 6:12
@liliscent - It's not redundant. The point here is that one can tell the construct is ill-formed without instantiating the template. But withalways_false
one can never tell a specialization won't exist.
– StoryTeller
Nov 26 '18 at 6:14
@StoryTeller I believe you're right. I was just thinking the wording could've been more clear, since the whole section [temp.res]/8 is talking about ill-formedness at a template's definition, not instantiated is implied from the context of that section.
– llllllllll
Nov 26 '18 at 6:25
add a comment |
This is a quality of implementation issue, it is ill-formed but if it is not instantiated no diagnostic is required as per [temp.res#8.1]p:
The validity of a template may be checked prior to any instantiation.
[ Note: Knowing which names are type names allows the syntax of every template to be checked in this way.
— end note
]
The program is ill-formed, no diagnostic required, if:
- no valid specialization can be generated for a template or a substatement of a constexpr if statement within a template and the template is not instantiated, or
and we can see from this live godbolt example MSVC does not diagnose this case. This is because MSVC is not using two-phase lookup but using /permissive-
changes this. clang even has an MSVC compatibility mode to emulate this using -fdelayed-template-parsing
.
We can see from this live godbolt using these two options clang no longer produces a diagnostic but MSVC does.
That rule is quite confusing.template<class T> SomeParticularError { static_assert(always_false<T>::value); };
is very common, but this rule seems to apply. That is, ifSomeParticularError
is not actually instantiated, this is ill-formed, NDR.
– llllllllll
Nov 26 '18 at 2:50
@liliscent - That rule doesn't apply.alwsys_false
may still have a specialization producing a true value. It's a non-deduced context for a reason.
– StoryTeller
Nov 26 '18 at 5:00
@StoryTeller If this is true, then the "and the template is not instantiated" part seems to be redundant, since a template will never be instantiated at its definition. In my previous comment, I thought that sentence means "it's not instantiated during the whole translation unit", if it refers to the whole TU, compiler has all the knowledge to determine whether there are other specializations ofalways_false
.
– llllllllll
Nov 26 '18 at 6:12
@liliscent - It's not redundant. The point here is that one can tell the construct is ill-formed without instantiating the template. But withalways_false
one can never tell a specialization won't exist.
– StoryTeller
Nov 26 '18 at 6:14
@StoryTeller I believe you're right. I was just thinking the wording could've been more clear, since the whole section [temp.res]/8 is talking about ill-formedness at a template's definition, not instantiated is implied from the context of that section.
– llllllllll
Nov 26 '18 at 6:25
add a comment |
This is a quality of implementation issue, it is ill-formed but if it is not instantiated no diagnostic is required as per [temp.res#8.1]p:
The validity of a template may be checked prior to any instantiation.
[ Note: Knowing which names are type names allows the syntax of every template to be checked in this way.
— end note
]
The program is ill-formed, no diagnostic required, if:
- no valid specialization can be generated for a template or a substatement of a constexpr if statement within a template and the template is not instantiated, or
and we can see from this live godbolt example MSVC does not diagnose this case. This is because MSVC is not using two-phase lookup but using /permissive-
changes this. clang even has an MSVC compatibility mode to emulate this using -fdelayed-template-parsing
.
We can see from this live godbolt using these two options clang no longer produces a diagnostic but MSVC does.
This is a quality of implementation issue, it is ill-formed but if it is not instantiated no diagnostic is required as per [temp.res#8.1]p:
The validity of a template may be checked prior to any instantiation.
[ Note: Knowing which names are type names allows the syntax of every template to be checked in this way.
— end note
]
The program is ill-formed, no diagnostic required, if:
- no valid specialization can be generated for a template or a substatement of a constexpr if statement within a template and the template is not instantiated, or
and we can see from this live godbolt example MSVC does not diagnose this case. This is because MSVC is not using two-phase lookup but using /permissive-
changes this. clang even has an MSVC compatibility mode to emulate this using -fdelayed-template-parsing
.
We can see from this live godbolt using these two options clang no longer produces a diagnostic but MSVC does.
edited Nov 26 '18 at 2:47
Swordfish
1
1
answered Nov 26 '18 at 2:30
Shafik YaghmourShafik Yaghmour
127k23327545
127k23327545
That rule is quite confusing.template<class T> SomeParticularError { static_assert(always_false<T>::value); };
is very common, but this rule seems to apply. That is, ifSomeParticularError
is not actually instantiated, this is ill-formed, NDR.
– llllllllll
Nov 26 '18 at 2:50
@liliscent - That rule doesn't apply.alwsys_false
may still have a specialization producing a true value. It's a non-deduced context for a reason.
– StoryTeller
Nov 26 '18 at 5:00
@StoryTeller If this is true, then the "and the template is not instantiated" part seems to be redundant, since a template will never be instantiated at its definition. In my previous comment, I thought that sentence means "it's not instantiated during the whole translation unit", if it refers to the whole TU, compiler has all the knowledge to determine whether there are other specializations ofalways_false
.
– llllllllll
Nov 26 '18 at 6:12
@liliscent - It's not redundant. The point here is that one can tell the construct is ill-formed without instantiating the template. But withalways_false
one can never tell a specialization won't exist.
– StoryTeller
Nov 26 '18 at 6:14
@StoryTeller I believe you're right. I was just thinking the wording could've been more clear, since the whole section [temp.res]/8 is talking about ill-formedness at a template's definition, not instantiated is implied from the context of that section.
– llllllllll
Nov 26 '18 at 6:25
add a comment |
That rule is quite confusing.template<class T> SomeParticularError { static_assert(always_false<T>::value); };
is very common, but this rule seems to apply. That is, ifSomeParticularError
is not actually instantiated, this is ill-formed, NDR.
– llllllllll
Nov 26 '18 at 2:50
@liliscent - That rule doesn't apply.alwsys_false
may still have a specialization producing a true value. It's a non-deduced context for a reason.
– StoryTeller
Nov 26 '18 at 5:00
@StoryTeller If this is true, then the "and the template is not instantiated" part seems to be redundant, since a template will never be instantiated at its definition. In my previous comment, I thought that sentence means "it's not instantiated during the whole translation unit", if it refers to the whole TU, compiler has all the knowledge to determine whether there are other specializations ofalways_false
.
– llllllllll
Nov 26 '18 at 6:12
@liliscent - It's not redundant. The point here is that one can tell the construct is ill-formed without instantiating the template. But withalways_false
one can never tell a specialization won't exist.
– StoryTeller
Nov 26 '18 at 6:14
@StoryTeller I believe you're right. I was just thinking the wording could've been more clear, since the whole section [temp.res]/8 is talking about ill-formedness at a template's definition, not instantiated is implied from the context of that section.
– llllllllll
Nov 26 '18 at 6:25
That rule is quite confusing.
template<class T> SomeParticularError { static_assert(always_false<T>::value); };
is very common, but this rule seems to apply. That is, if SomeParticularError
is not actually instantiated, this is ill-formed, NDR.– llllllllll
Nov 26 '18 at 2:50
That rule is quite confusing.
template<class T> SomeParticularError { static_assert(always_false<T>::value); };
is very common, but this rule seems to apply. That is, if SomeParticularError
is not actually instantiated, this is ill-formed, NDR.– llllllllll
Nov 26 '18 at 2:50
@liliscent - That rule doesn't apply.
alwsys_false
may still have a specialization producing a true value. It's a non-deduced context for a reason.– StoryTeller
Nov 26 '18 at 5:00
@liliscent - That rule doesn't apply.
alwsys_false
may still have a specialization producing a true value. It's a non-deduced context for a reason.– StoryTeller
Nov 26 '18 at 5:00
@StoryTeller If this is true, then the "and the template is not instantiated" part seems to be redundant, since a template will never be instantiated at its definition. In my previous comment, I thought that sentence means "it's not instantiated during the whole translation unit", if it refers to the whole TU, compiler has all the knowledge to determine whether there are other specializations of
always_false
.– llllllllll
Nov 26 '18 at 6:12
@StoryTeller If this is true, then the "and the template is not instantiated" part seems to be redundant, since a template will never be instantiated at its definition. In my previous comment, I thought that sentence means "it's not instantiated during the whole translation unit", if it refers to the whole TU, compiler has all the knowledge to determine whether there are other specializations of
always_false
.– llllllllll
Nov 26 '18 at 6:12
@liliscent - It's not redundant. The point here is that one can tell the construct is ill-formed without instantiating the template. But with
always_false
one can never tell a specialization won't exist.– StoryTeller
Nov 26 '18 at 6:14
@liliscent - It's not redundant. The point here is that one can tell the construct is ill-formed without instantiating the template. But with
always_false
one can never tell a specialization won't exist.– StoryTeller
Nov 26 '18 at 6:14
@StoryTeller I believe you're right. I was just thinking the wording could've been more clear, since the whole section [temp.res]/8 is talking about ill-formedness at a template's definition, not instantiated is implied from the context of that section.
– llllllllll
Nov 26 '18 at 6:25
@StoryTeller I believe you're right. I was just thinking the wording could've been more clear, since the whole section [temp.res]/8 is talking about ill-formedness at a template's definition, not instantiated is implied from the context of that section.
– llllllllll
Nov 26 '18 at 6:25
add a comment |
Names inside a function template
are either dependent, i.e., the entity depends on the template
parameters in some form, or they are independent, i.e., there is no indication that it depends on a template
parameter. Independent names are looked up when the function template
is defined. Dependent names are looked up during template
instantiation, i.e., at the name doesn’t need to be defined when the function template
is defined. Failure to look-up a name is an error. The details of this process are a bit more involved and fill most of the chapter on template
s.
In your case some
is an independent name while the T::
qualification makes random_name
a dependent name.
some ill-formed
is a syntax error though, so I don't think it gets so far as dependent name analysis
– M.M
Nov 26 '18 at 2:51
@M.M.: the error message implies it tried to locate the name...
– Dietmar Kühl
Nov 26 '18 at 3:01
add a comment |
Names inside a function template
are either dependent, i.e., the entity depends on the template
parameters in some form, or they are independent, i.e., there is no indication that it depends on a template
parameter. Independent names are looked up when the function template
is defined. Dependent names are looked up during template
instantiation, i.e., at the name doesn’t need to be defined when the function template
is defined. Failure to look-up a name is an error. The details of this process are a bit more involved and fill most of the chapter on template
s.
In your case some
is an independent name while the T::
qualification makes random_name
a dependent name.
some ill-formed
is a syntax error though, so I don't think it gets so far as dependent name analysis
– M.M
Nov 26 '18 at 2:51
@M.M.: the error message implies it tried to locate the name...
– Dietmar Kühl
Nov 26 '18 at 3:01
add a comment |
Names inside a function template
are either dependent, i.e., the entity depends on the template
parameters in some form, or they are independent, i.e., there is no indication that it depends on a template
parameter. Independent names are looked up when the function template
is defined. Dependent names are looked up during template
instantiation, i.e., at the name doesn’t need to be defined when the function template
is defined. Failure to look-up a name is an error. The details of this process are a bit more involved and fill most of the chapter on template
s.
In your case some
is an independent name while the T::
qualification makes random_name
a dependent name.
Names inside a function template
are either dependent, i.e., the entity depends on the template
parameters in some form, or they are independent, i.e., there is no indication that it depends on a template
parameter. Independent names are looked up when the function template
is defined. Dependent names are looked up during template
instantiation, i.e., at the name doesn’t need to be defined when the function template
is defined. Failure to look-up a name is an error. The details of this process are a bit more involved and fill most of the chapter on template
s.
In your case some
is an independent name while the T::
qualification makes random_name
a dependent name.
answered Nov 26 '18 at 2:38
Dietmar KühlDietmar Kühl
127k9157321
127k9157321
some ill-formed
is a syntax error though, so I don't think it gets so far as dependent name analysis
– M.M
Nov 26 '18 at 2:51
@M.M.: the error message implies it tried to locate the name...
– Dietmar Kühl
Nov 26 '18 at 3:01
add a comment |
some ill-formed
is a syntax error though, so I don't think it gets so far as dependent name analysis
– M.M
Nov 26 '18 at 2:51
@M.M.: the error message implies it tried to locate the name...
– Dietmar Kühl
Nov 26 '18 at 3:01
some ill-formed
is a syntax error though, so I don't think it gets so far as dependent name analysis– M.M
Nov 26 '18 at 2:51
some ill-formed
is a syntax error though, so I don't think it gets so far as dependent name analysis– M.M
Nov 26 '18 at 2:51
@M.M.: the error message implies it tried to locate the name...
– Dietmar Kühl
Nov 26 '18 at 3:01
@M.M.: the error message implies it tried to locate the name...
– Dietmar Kühl
Nov 26 '18 at 3:01
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%2f53473934%2fc-standard-requirements-to-templates-that-are-not-instantiated%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