C++ nested template issueWhat are the differences between a pointer variable and a reference variable in C++?The Definitive C++ Book Guide and ListWhy can templates only be implemented in the header file?Where and why do I have to put the “template” and “typename” keywords?What is the “-->” operator in C++?C++11 introduced a standardized memory model. What does it mean? And how is it going to affect C++ programming?function template specialization in a namespaceInvalid use of incomplete type for partial template specialization c++Is it legal to perform partial in-class specialization of a member template class in derived classC++ template alias and partial template class specializations
Set multicolumn to a exact width
Find the probability that the 8th woman to appear is in 17th position.
Why do all the teams that I have worked with always finish a sprint without completion of all the stories?
Why is the voltage measurement of this circuit different when the switch is on?
Is it damaging to turn off a small fridge for two days every week?
Archery in modern conflicts
Computing a trigonometric integral
How do I turn off a repeating trade?
Hand soldering SMD 1206 components
Should my manager be aware of private LinkedIn approaches I receive? How to politely have this happen?
Why aren't cotton tents more popular?
Where can I find a database of galactic spectra?
Trainee keeps missing deadlines for independent learning
Impossible darts scores
How dangerous are set-size assumptions?
Require advice on power conservation for backpacking trip
Can humans ever directly see a few photons at a time? Can a human see a single photon?
Why is C++ initial allocation so much larger than C's?
Is there a maximum distance from a planet that a moon can orbit?
What are the penalties for overstaying in USA?
“D’entre eux” to mean “of them”
Underbar nabla symbol doesn't work
Would it be a copyright violation if I made a character’s full name refer to a song?
How to get cool night-vision without lame drawbacks?
C++ nested template issue
What are the differences between a pointer variable and a reference variable in C++?The Definitive C++ Book Guide and ListWhy can templates only be implemented in the header file?Where and why do I have to put the “template” and “typename” keywords?What is the “-->” operator in C++?C++11 introduced a standardized memory model. What does it mean? And how is it going to affect C++ programming?function template specialization in a namespaceInvalid use of incomplete type for partial template specialization c++Is it legal to perform partial in-class specialization of a member template class in derived classC++ template alias and partial template class specializations
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
GCC 7.3.1 compile the below code while clang 8.0.0 does not.
I would like to know if this syntax is valid (in which case I will report it as a possible clang bug).
Thanks for your help.
template<typename FOO>
struct Foo
using Value = int;
template<Value VALUE>
struct Bar;
;
template<typename FOO>
template<typename Foo<FOO>::Value VALUE>
struct Foo<FOO>::Bar static void test(); ;
template<typename FOO>
template<typename Foo<FOO>::Value VALUE>
void Foo<FOO>::Bar<VALUE>::test()
int main() return 0;
The error message with clang is the following:
error: nested name specifier 'Foo<FOO>::Bar<VALUE>::' for declaration does not refer into a class, class template or class template partial specialization
void Foo<FOO>::Bar<VALUE>::test()
~~~~~~~~~~~~~~~~~~~~~~^
1 error generated.
EDIT:
clang possible bug report here.
c++ templates g++ language-lawyer clang++
add a comment |
GCC 7.3.1 compile the below code while clang 8.0.0 does not.
I would like to know if this syntax is valid (in which case I will report it as a possible clang bug).
Thanks for your help.
template<typename FOO>
struct Foo
using Value = int;
template<Value VALUE>
struct Bar;
;
template<typename FOO>
template<typename Foo<FOO>::Value VALUE>
struct Foo<FOO>::Bar static void test(); ;
template<typename FOO>
template<typename Foo<FOO>::Value VALUE>
void Foo<FOO>::Bar<VALUE>::test()
int main() return 0;
The error message with clang is the following:
error: nested name specifier 'Foo<FOO>::Bar<VALUE>::' for declaration does not refer into a class, class template or class template partial specialization
void Foo<FOO>::Bar<VALUE>::test()
~~~~~~~~~~~~~~~~~~~~~~^
1 error generated.
EDIT:
clang possible bug report here.
c++ templates g++ language-lawyer clang++
There are several core issues about template types equivalence and aliases (like 1979). Might be related.
– Language Lawyer
Mar 25 at 12:59
add a comment |
GCC 7.3.1 compile the below code while clang 8.0.0 does not.
I would like to know if this syntax is valid (in which case I will report it as a possible clang bug).
Thanks for your help.
template<typename FOO>
struct Foo
using Value = int;
template<Value VALUE>
struct Bar;
;
template<typename FOO>
template<typename Foo<FOO>::Value VALUE>
struct Foo<FOO>::Bar static void test(); ;
template<typename FOO>
template<typename Foo<FOO>::Value VALUE>
void Foo<FOO>::Bar<VALUE>::test()
int main() return 0;
The error message with clang is the following:
error: nested name specifier 'Foo<FOO>::Bar<VALUE>::' for declaration does not refer into a class, class template or class template partial specialization
void Foo<FOO>::Bar<VALUE>::test()
~~~~~~~~~~~~~~~~~~~~~~^
1 error generated.
EDIT:
clang possible bug report here.
c++ templates g++ language-lawyer clang++
GCC 7.3.1 compile the below code while clang 8.0.0 does not.
I would like to know if this syntax is valid (in which case I will report it as a possible clang bug).
Thanks for your help.
template<typename FOO>
struct Foo
using Value = int;
template<Value VALUE>
struct Bar;
;
template<typename FOO>
template<typename Foo<FOO>::Value VALUE>
struct Foo<FOO>::Bar static void test(); ;
template<typename FOO>
template<typename Foo<FOO>::Value VALUE>
void Foo<FOO>::Bar<VALUE>::test()
int main() return 0;
The error message with clang is the following:
error: nested name specifier 'Foo<FOO>::Bar<VALUE>::' for declaration does not refer into a class, class template or class template partial specialization
void Foo<FOO>::Bar<VALUE>::test()
~~~~~~~~~~~~~~~~~~~~~~^
1 error generated.
EDIT:
clang possible bug report here.
c++ templates g++ language-lawyer clang++
c++ templates g++ language-lawyer clang++
edited Mar 26 at 0:43
Ankur deDev
asked Mar 25 at 9:07
Ankur deDevAnkur deDev
1957 bronze badges
1957 bronze badges
There are several core issues about template types equivalence and aliases (like 1979). Might be related.
– Language Lawyer
Mar 25 at 12:59
add a comment |
There are several core issues about template types equivalence and aliases (like 1979). Might be related.
– Language Lawyer
Mar 25 at 12:59
There are several core issues about template types equivalence and aliases (like 1979). Might be related.
– Language Lawyer
Mar 25 at 12:59
There are several core issues about template types equivalence and aliases (like 1979). Might be related.
– Language Lawyer
Mar 25 at 12:59
add a comment |
2 Answers
2
active
oldest
votes
This is an interesting case! My position whether it is a compiler or standard problem is similar to @lubgr, but I wanted to add some more insights.
ICC also have some problems with your construct, which might suggest that this is more deeply rooted in standard (still, gcc might be correct here). It fails with error: "template argument list must match the parameter list" - this might mean that for both compilers this:
template<typename FOO>
template<typename Foo<FOO>::Value VALUE>
are not identical with original definition of Foo
. It seems to be a bug of both compilers, but I've learned to be cautious when two different compilers share similar problems.
Extracting definition of Value
from original template to separate one fixes the case (code on Compiler Explorer):
template<typename T>
struct X
using Value = int;
;
template<typename FOO>
struct Foo
template<typename X<FOO>::Value VALUE>
struct Bar;
;
template<typename FOO>
template<typename X<FOO>::Value VALUE>
struct Foo<FOO>::Bar static void test(); ;
template<typename FOO>
template<typename X<FOO>::Value VALUE>
void Foo<FOO>::Bar<VALUE>::test()
int main() return 0;
You can fix this as well by simply using hardcoded Value
type (code on Compiler Explorer) - but this is not what you need probably:
template<typename FOO>
struct Foo
template<int VALUE>
struct Bar;
;
template<typename FOO>
template<int VALUE>
struct Foo<FOO>::Bar static void test(); ;
template<typename FOO>
template<int VALUE>
void Foo<FOO>::Bar<VALUE>::test()
int main() return 0;
Hope it helps!
Thanks, your first example was helpful to better understand the issue.
– Ankur deDev
Mar 26 at 0:29
add a comment |
From [temp.mem.class/1], we have
A member class of a class template may be defined outside the class template definition in which it is declared.
Furthermore, in a non-template context, [class.nest/2] tells us:
Member functions and static data members of a nested class can be defined in a namespace scope enclosing the definition of their class.
Let's hence construct a simpler example and verify that the definition of a member function of a nested type is allowed to be separated from the definition of the nested, non-template type itself. In analogy to the types in your snippet:
template <class FOO>
struct Foo
// Simpler, Bar is not a template
struct Bar;
;
// Definition of Bar outside of Foo as before
template <class FOO>
struct Foo<FOO>::Bar
static void test();
;
And now the critical part, the definition of Bar::test()
outside of Bar
itself:
template <class FOO>
void Foo<FOO>::Bar::test()
This happily compiles with both gcc-8
and clang
(trunk as well as a much older stable version).
I might be misunderstanding something here, but my conclusion is that the syntax to define Foo::Bar::test()
outside of Foo
and outside of Bar
is indeed fine, and clang
should compile it as gcc
does.
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%2f55334378%2fc-nested-template-issue%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 an interesting case! My position whether it is a compiler or standard problem is similar to @lubgr, but I wanted to add some more insights.
ICC also have some problems with your construct, which might suggest that this is more deeply rooted in standard (still, gcc might be correct here). It fails with error: "template argument list must match the parameter list" - this might mean that for both compilers this:
template<typename FOO>
template<typename Foo<FOO>::Value VALUE>
are not identical with original definition of Foo
. It seems to be a bug of both compilers, but I've learned to be cautious when two different compilers share similar problems.
Extracting definition of Value
from original template to separate one fixes the case (code on Compiler Explorer):
template<typename T>
struct X
using Value = int;
;
template<typename FOO>
struct Foo
template<typename X<FOO>::Value VALUE>
struct Bar;
;
template<typename FOO>
template<typename X<FOO>::Value VALUE>
struct Foo<FOO>::Bar static void test(); ;
template<typename FOO>
template<typename X<FOO>::Value VALUE>
void Foo<FOO>::Bar<VALUE>::test()
int main() return 0;
You can fix this as well by simply using hardcoded Value
type (code on Compiler Explorer) - but this is not what you need probably:
template<typename FOO>
struct Foo
template<int VALUE>
struct Bar;
;
template<typename FOO>
template<int VALUE>
struct Foo<FOO>::Bar static void test(); ;
template<typename FOO>
template<int VALUE>
void Foo<FOO>::Bar<VALUE>::test()
int main() return 0;
Hope it helps!
Thanks, your first example was helpful to better understand the issue.
– Ankur deDev
Mar 26 at 0:29
add a comment |
This is an interesting case! My position whether it is a compiler or standard problem is similar to @lubgr, but I wanted to add some more insights.
ICC also have some problems with your construct, which might suggest that this is more deeply rooted in standard (still, gcc might be correct here). It fails with error: "template argument list must match the parameter list" - this might mean that for both compilers this:
template<typename FOO>
template<typename Foo<FOO>::Value VALUE>
are not identical with original definition of Foo
. It seems to be a bug of both compilers, but I've learned to be cautious when two different compilers share similar problems.
Extracting definition of Value
from original template to separate one fixes the case (code on Compiler Explorer):
template<typename T>
struct X
using Value = int;
;
template<typename FOO>
struct Foo
template<typename X<FOO>::Value VALUE>
struct Bar;
;
template<typename FOO>
template<typename X<FOO>::Value VALUE>
struct Foo<FOO>::Bar static void test(); ;
template<typename FOO>
template<typename X<FOO>::Value VALUE>
void Foo<FOO>::Bar<VALUE>::test()
int main() return 0;
You can fix this as well by simply using hardcoded Value
type (code on Compiler Explorer) - but this is not what you need probably:
template<typename FOO>
struct Foo
template<int VALUE>
struct Bar;
;
template<typename FOO>
template<int VALUE>
struct Foo<FOO>::Bar static void test(); ;
template<typename FOO>
template<int VALUE>
void Foo<FOO>::Bar<VALUE>::test()
int main() return 0;
Hope it helps!
Thanks, your first example was helpful to better understand the issue.
– Ankur deDev
Mar 26 at 0:29
add a comment |
This is an interesting case! My position whether it is a compiler or standard problem is similar to @lubgr, but I wanted to add some more insights.
ICC also have some problems with your construct, which might suggest that this is more deeply rooted in standard (still, gcc might be correct here). It fails with error: "template argument list must match the parameter list" - this might mean that for both compilers this:
template<typename FOO>
template<typename Foo<FOO>::Value VALUE>
are not identical with original definition of Foo
. It seems to be a bug of both compilers, but I've learned to be cautious when two different compilers share similar problems.
Extracting definition of Value
from original template to separate one fixes the case (code on Compiler Explorer):
template<typename T>
struct X
using Value = int;
;
template<typename FOO>
struct Foo
template<typename X<FOO>::Value VALUE>
struct Bar;
;
template<typename FOO>
template<typename X<FOO>::Value VALUE>
struct Foo<FOO>::Bar static void test(); ;
template<typename FOO>
template<typename X<FOO>::Value VALUE>
void Foo<FOO>::Bar<VALUE>::test()
int main() return 0;
You can fix this as well by simply using hardcoded Value
type (code on Compiler Explorer) - but this is not what you need probably:
template<typename FOO>
struct Foo
template<int VALUE>
struct Bar;
;
template<typename FOO>
template<int VALUE>
struct Foo<FOO>::Bar static void test(); ;
template<typename FOO>
template<int VALUE>
void Foo<FOO>::Bar<VALUE>::test()
int main() return 0;
Hope it helps!
This is an interesting case! My position whether it is a compiler or standard problem is similar to @lubgr, but I wanted to add some more insights.
ICC also have some problems with your construct, which might suggest that this is more deeply rooted in standard (still, gcc might be correct here). It fails with error: "template argument list must match the parameter list" - this might mean that for both compilers this:
template<typename FOO>
template<typename Foo<FOO>::Value VALUE>
are not identical with original definition of Foo
. It seems to be a bug of both compilers, but I've learned to be cautious when two different compilers share similar problems.
Extracting definition of Value
from original template to separate one fixes the case (code on Compiler Explorer):
template<typename T>
struct X
using Value = int;
;
template<typename FOO>
struct Foo
template<typename X<FOO>::Value VALUE>
struct Bar;
;
template<typename FOO>
template<typename X<FOO>::Value VALUE>
struct Foo<FOO>::Bar static void test(); ;
template<typename FOO>
template<typename X<FOO>::Value VALUE>
void Foo<FOO>::Bar<VALUE>::test()
int main() return 0;
You can fix this as well by simply using hardcoded Value
type (code on Compiler Explorer) - but this is not what you need probably:
template<typename FOO>
struct Foo
template<int VALUE>
struct Bar;
;
template<typename FOO>
template<int VALUE>
struct Foo<FOO>::Bar static void test(); ;
template<typename FOO>
template<int VALUE>
void Foo<FOO>::Bar<VALUE>::test()
int main() return 0;
Hope it helps!
answered Mar 25 at 12:18
Michał ŁośMichał Łoś
5183 silver badges13 bronze badges
5183 silver badges13 bronze badges
Thanks, your first example was helpful to better understand the issue.
– Ankur deDev
Mar 26 at 0:29
add a comment |
Thanks, your first example was helpful to better understand the issue.
– Ankur deDev
Mar 26 at 0:29
Thanks, your first example was helpful to better understand the issue.
– Ankur deDev
Mar 26 at 0:29
Thanks, your first example was helpful to better understand the issue.
– Ankur deDev
Mar 26 at 0:29
add a comment |
From [temp.mem.class/1], we have
A member class of a class template may be defined outside the class template definition in which it is declared.
Furthermore, in a non-template context, [class.nest/2] tells us:
Member functions and static data members of a nested class can be defined in a namespace scope enclosing the definition of their class.
Let's hence construct a simpler example and verify that the definition of a member function of a nested type is allowed to be separated from the definition of the nested, non-template type itself. In analogy to the types in your snippet:
template <class FOO>
struct Foo
// Simpler, Bar is not a template
struct Bar;
;
// Definition of Bar outside of Foo as before
template <class FOO>
struct Foo<FOO>::Bar
static void test();
;
And now the critical part, the definition of Bar::test()
outside of Bar
itself:
template <class FOO>
void Foo<FOO>::Bar::test()
This happily compiles with both gcc-8
and clang
(trunk as well as a much older stable version).
I might be misunderstanding something here, but my conclusion is that the syntax to define Foo::Bar::test()
outside of Foo
and outside of Bar
is indeed fine, and clang
should compile it as gcc
does.
add a comment |
From [temp.mem.class/1], we have
A member class of a class template may be defined outside the class template definition in which it is declared.
Furthermore, in a non-template context, [class.nest/2] tells us:
Member functions and static data members of a nested class can be defined in a namespace scope enclosing the definition of their class.
Let's hence construct a simpler example and verify that the definition of a member function of a nested type is allowed to be separated from the definition of the nested, non-template type itself. In analogy to the types in your snippet:
template <class FOO>
struct Foo
// Simpler, Bar is not a template
struct Bar;
;
// Definition of Bar outside of Foo as before
template <class FOO>
struct Foo<FOO>::Bar
static void test();
;
And now the critical part, the definition of Bar::test()
outside of Bar
itself:
template <class FOO>
void Foo<FOO>::Bar::test()
This happily compiles with both gcc-8
and clang
(trunk as well as a much older stable version).
I might be misunderstanding something here, but my conclusion is that the syntax to define Foo::Bar::test()
outside of Foo
and outside of Bar
is indeed fine, and clang
should compile it as gcc
does.
add a comment |
From [temp.mem.class/1], we have
A member class of a class template may be defined outside the class template definition in which it is declared.
Furthermore, in a non-template context, [class.nest/2] tells us:
Member functions and static data members of a nested class can be defined in a namespace scope enclosing the definition of their class.
Let's hence construct a simpler example and verify that the definition of a member function of a nested type is allowed to be separated from the definition of the nested, non-template type itself. In analogy to the types in your snippet:
template <class FOO>
struct Foo
// Simpler, Bar is not a template
struct Bar;
;
// Definition of Bar outside of Foo as before
template <class FOO>
struct Foo<FOO>::Bar
static void test();
;
And now the critical part, the definition of Bar::test()
outside of Bar
itself:
template <class FOO>
void Foo<FOO>::Bar::test()
This happily compiles with both gcc-8
and clang
(trunk as well as a much older stable version).
I might be misunderstanding something here, but my conclusion is that the syntax to define Foo::Bar::test()
outside of Foo
and outside of Bar
is indeed fine, and clang
should compile it as gcc
does.
From [temp.mem.class/1], we have
A member class of a class template may be defined outside the class template definition in which it is declared.
Furthermore, in a non-template context, [class.nest/2] tells us:
Member functions and static data members of a nested class can be defined in a namespace scope enclosing the definition of their class.
Let's hence construct a simpler example and verify that the definition of a member function of a nested type is allowed to be separated from the definition of the nested, non-template type itself. In analogy to the types in your snippet:
template <class FOO>
struct Foo
// Simpler, Bar is not a template
struct Bar;
;
// Definition of Bar outside of Foo as before
template <class FOO>
struct Foo<FOO>::Bar
static void test();
;
And now the critical part, the definition of Bar::test()
outside of Bar
itself:
template <class FOO>
void Foo<FOO>::Bar::test()
This happily compiles with both gcc-8
and clang
(trunk as well as a much older stable version).
I might be misunderstanding something here, but my conclusion is that the syntax to define Foo::Bar::test()
outside of Foo
and outside of Bar
is indeed fine, and clang
should compile it as gcc
does.
edited Mar 25 at 10:09
answered Mar 25 at 9:37
lubgrlubgr
19.7k3 gold badges30 silver badges66 bronze badges
19.7k3 gold badges30 silver badges66 bronze badges
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%2f55334378%2fc-nested-template-issue%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
There are several core issues about template types equivalence and aliases (like 1979). Might be related.
– Language Lawyer
Mar 25 at 12:59