Template parameter type is treated as complete by the compiler, but its definition isn't yet visible
Assume I have the following code snippet:
template <class T>
class Bar
{
// static_assert(sizeof(T) > 0); // (1)
public:
void method()
{
static_assert(sizeof(T) > 0); // (2)
}
};
class Foo; // (3)
template class Bar<Foo>; // (4)
class Foo{}; // (5)
If we uncomment the line (1), we get a compile-time error "incomplete type T", and it seems to be clear: class Bar
instantiation is launched by (4), and at that point class Foo
is only forward-declared by (3) and not yet defined by (5).
But if the line (1) is commented out, then this code compiles with no errors, and it confuses me: (4) is an explicit template instantiation definition and it forces the compiler to generate void method()
code, and line (2) should also generate the same error, since the definition of Foo
is made later in (5).
What do I miss, why does the code from the snippet compiles?
UPDATE: Code compiles under GCC 8.2.0 and MSVC 19.16.27025.1, but under Clang 7.0.0 it gives an "incomplete type" error.
c++ templates incomplete-type template-instantiation
add a comment |
Assume I have the following code snippet:
template <class T>
class Bar
{
// static_assert(sizeof(T) > 0); // (1)
public:
void method()
{
static_assert(sizeof(T) > 0); // (2)
}
};
class Foo; // (3)
template class Bar<Foo>; // (4)
class Foo{}; // (5)
If we uncomment the line (1), we get a compile-time error "incomplete type T", and it seems to be clear: class Bar
instantiation is launched by (4), and at that point class Foo
is only forward-declared by (3) and not yet defined by (5).
But if the line (1) is commented out, then this code compiles with no errors, and it confuses me: (4) is an explicit template instantiation definition and it forces the compiler to generate void method()
code, and line (2) should also generate the same error, since the definition of Foo
is made later in (5).
What do I miss, why does the code from the snippet compiles?
UPDATE: Code compiles under GCC 8.2.0 and MSVC 19.16.27025.1, but under Clang 7.0.0 it gives an "incomplete type" error.
c++ templates incomplete-type template-instantiation
Compiles with what tool chain (because it pukes as-is with vc++ (19.00.24215.1) ? Include that in your question.
– WhozCraig
Jan 1 at 18:05
@WhozCraig Thanks, I added description. It turns out that clang doesn't compile this.
– undermind
Jan 1 at 18:57
add a comment |
Assume I have the following code snippet:
template <class T>
class Bar
{
// static_assert(sizeof(T) > 0); // (1)
public:
void method()
{
static_assert(sizeof(T) > 0); // (2)
}
};
class Foo; // (3)
template class Bar<Foo>; // (4)
class Foo{}; // (5)
If we uncomment the line (1), we get a compile-time error "incomplete type T", and it seems to be clear: class Bar
instantiation is launched by (4), and at that point class Foo
is only forward-declared by (3) and not yet defined by (5).
But if the line (1) is commented out, then this code compiles with no errors, and it confuses me: (4) is an explicit template instantiation definition and it forces the compiler to generate void method()
code, and line (2) should also generate the same error, since the definition of Foo
is made later in (5).
What do I miss, why does the code from the snippet compiles?
UPDATE: Code compiles under GCC 8.2.0 and MSVC 19.16.27025.1, but under Clang 7.0.0 it gives an "incomplete type" error.
c++ templates incomplete-type template-instantiation
Assume I have the following code snippet:
template <class T>
class Bar
{
// static_assert(sizeof(T) > 0); // (1)
public:
void method()
{
static_assert(sizeof(T) > 0); // (2)
}
};
class Foo; // (3)
template class Bar<Foo>; // (4)
class Foo{}; // (5)
If we uncomment the line (1), we get a compile-time error "incomplete type T", and it seems to be clear: class Bar
instantiation is launched by (4), and at that point class Foo
is only forward-declared by (3) and not yet defined by (5).
But if the line (1) is commented out, then this code compiles with no errors, and it confuses me: (4) is an explicit template instantiation definition and it forces the compiler to generate void method()
code, and line (2) should also generate the same error, since the definition of Foo
is made later in (5).
What do I miss, why does the code from the snippet compiles?
UPDATE: Code compiles under GCC 8.2.0 and MSVC 19.16.27025.1, but under Clang 7.0.0 it gives an "incomplete type" error.
c++ templates incomplete-type template-instantiation
c++ templates incomplete-type template-instantiation
edited Jan 1 at 18:56
undermind
asked Jan 1 at 17:50
undermindundermind
944521
944521
Compiles with what tool chain (because it pukes as-is with vc++ (19.00.24215.1) ? Include that in your question.
– WhozCraig
Jan 1 at 18:05
@WhozCraig Thanks, I added description. It turns out that clang doesn't compile this.
– undermind
Jan 1 at 18:57
add a comment |
Compiles with what tool chain (because it pukes as-is with vc++ (19.00.24215.1) ? Include that in your question.
– WhozCraig
Jan 1 at 18:05
@WhozCraig Thanks, I added description. It turns out that clang doesn't compile this.
– undermind
Jan 1 at 18:57
Compiles with what tool chain (because it pukes as-is with vc++ (19.00.24215.1) ? Include that in your question.
– WhozCraig
Jan 1 at 18:05
Compiles with what tool chain (because it pukes as-is with vc++ (19.00.24215.1) ? Include that in your question.
– WhozCraig
Jan 1 at 18:05
@WhozCraig Thanks, I added description. It turns out that clang doesn't compile this.
– undermind
Jan 1 at 18:57
@WhozCraig Thanks, I added description. It turns out that clang doesn't compile this.
– undermind
Jan 1 at 18:57
add a comment |
1 Answer
1
active
oldest
votes
As per the standard goes, during implicit instantiation only the declaration of member functions are instantiated but not their definition.
[temp.inst]/2 - The implicit instantiation of a class template specialization causes
- the implicit instantiation of the declarations, but not of the definitions, of the non-deleted class member functions, member classes, scoped member enumerations, static data members, member templates, and friends ...
but it doesn't say the same about explicit instantiations. The whole class is instantiated which means that it instantiates the definition of method()
and at that point Foo
isn't complete.
[temp.explicit]/11 - An explicit instantiation definition that names a class template specialization explicitly instantiates the class template specialization and is an explicit instantiation definition of only those members that have been defined at the point of instantiation.
clang rejects the code.
Indeed, clang doesn't compile it (I updated question description). So, is it a correct behavior?
– undermind
Jan 1 at 19:04
@undermind - yes, clang is correct
– Jans
Jan 1 at 19:24
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%2f53997632%2ftemplate-parameter-type-is-treated-as-complete-by-the-compiler-but-its-definiti%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
As per the standard goes, during implicit instantiation only the declaration of member functions are instantiated but not their definition.
[temp.inst]/2 - The implicit instantiation of a class template specialization causes
- the implicit instantiation of the declarations, but not of the definitions, of the non-deleted class member functions, member classes, scoped member enumerations, static data members, member templates, and friends ...
but it doesn't say the same about explicit instantiations. The whole class is instantiated which means that it instantiates the definition of method()
and at that point Foo
isn't complete.
[temp.explicit]/11 - An explicit instantiation definition that names a class template specialization explicitly instantiates the class template specialization and is an explicit instantiation definition of only those members that have been defined at the point of instantiation.
clang rejects the code.
Indeed, clang doesn't compile it (I updated question description). So, is it a correct behavior?
– undermind
Jan 1 at 19:04
@undermind - yes, clang is correct
– Jans
Jan 1 at 19:24
add a comment |
As per the standard goes, during implicit instantiation only the declaration of member functions are instantiated but not their definition.
[temp.inst]/2 - The implicit instantiation of a class template specialization causes
- the implicit instantiation of the declarations, but not of the definitions, of the non-deleted class member functions, member classes, scoped member enumerations, static data members, member templates, and friends ...
but it doesn't say the same about explicit instantiations. The whole class is instantiated which means that it instantiates the definition of method()
and at that point Foo
isn't complete.
[temp.explicit]/11 - An explicit instantiation definition that names a class template specialization explicitly instantiates the class template specialization and is an explicit instantiation definition of only those members that have been defined at the point of instantiation.
clang rejects the code.
Indeed, clang doesn't compile it (I updated question description). So, is it a correct behavior?
– undermind
Jan 1 at 19:04
@undermind - yes, clang is correct
– Jans
Jan 1 at 19:24
add a comment |
As per the standard goes, during implicit instantiation only the declaration of member functions are instantiated but not their definition.
[temp.inst]/2 - The implicit instantiation of a class template specialization causes
- the implicit instantiation of the declarations, but not of the definitions, of the non-deleted class member functions, member classes, scoped member enumerations, static data members, member templates, and friends ...
but it doesn't say the same about explicit instantiations. The whole class is instantiated which means that it instantiates the definition of method()
and at that point Foo
isn't complete.
[temp.explicit]/11 - An explicit instantiation definition that names a class template specialization explicitly instantiates the class template specialization and is an explicit instantiation definition of only those members that have been defined at the point of instantiation.
clang rejects the code.
As per the standard goes, during implicit instantiation only the declaration of member functions are instantiated but not their definition.
[temp.inst]/2 - The implicit instantiation of a class template specialization causes
- the implicit instantiation of the declarations, but not of the definitions, of the non-deleted class member functions, member classes, scoped member enumerations, static data members, member templates, and friends ...
but it doesn't say the same about explicit instantiations. The whole class is instantiated which means that it instantiates the definition of method()
and at that point Foo
isn't complete.
[temp.explicit]/11 - An explicit instantiation definition that names a class template specialization explicitly instantiates the class template specialization and is an explicit instantiation definition of only those members that have been defined at the point of instantiation.
clang rejects the code.
edited Jan 2 at 1:08
Rakete1111
35k1083118
35k1083118
answered Jan 1 at 18:24
JansJans
9,02422635
9,02422635
Indeed, clang doesn't compile it (I updated question description). So, is it a correct behavior?
– undermind
Jan 1 at 19:04
@undermind - yes, clang is correct
– Jans
Jan 1 at 19:24
add a comment |
Indeed, clang doesn't compile it (I updated question description). So, is it a correct behavior?
– undermind
Jan 1 at 19:04
@undermind - yes, clang is correct
– Jans
Jan 1 at 19:24
Indeed, clang doesn't compile it (I updated question description). So, is it a correct behavior?
– undermind
Jan 1 at 19:04
Indeed, clang doesn't compile it (I updated question description). So, is it a correct behavior?
– undermind
Jan 1 at 19:04
@undermind - yes, clang is correct
– Jans
Jan 1 at 19:24
@undermind - yes, clang is correct
– Jans
Jan 1 at 19:24
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%2f53997632%2ftemplate-parameter-type-is-treated-as-complete-by-the-compiler-but-its-definiti%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
Compiles with what tool chain (because it pukes as-is with vc++ (19.00.24215.1) ? Include that in your question.
– WhozCraig
Jan 1 at 18:05
@WhozCraig Thanks, I added description. It turns out that clang doesn't compile this.
– undermind
Jan 1 at 18:57