Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #71515 > unrolled thread
| Started by | Paavo Helde <myfirstname@osa.pri.ee> |
|---|---|
| First post | 2020-01-22 17:01 +0200 |
| Last post | 2020-01-27 01:40 -0800 |
| Articles | 4 — 3 participants |
Back to article view | Back to comp.lang.c++
Template alias destructor call Paavo Helde <myfirstname@osa.pri.ee> - 2020-01-22 17:01 +0200
Re: Template alias destructor call "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2020-01-23 11:26 +0100
Re: Template alias destructor call Paavo Helde <myfirstname@osa.pri.ee> - 2020-01-23 13:09 +0200
Re: Template alias destructor call Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-01-27 01:40 -0800
| From | Paavo Helde <myfirstname@osa.pri.ee> |
|---|---|
| Date | 2020-01-22 17:01 +0200 |
| Subject | Template alias destructor call |
| Message-ID | <r09o3o$a96$1@dont-email.me> |
Please consider:
#include <new>
template <typename T, typename U>
class A {};
template <typename T>
using B = A<T, int>;
template <typename T>
void foo(B<T>* x) {
x->~B<T>(); // this line failing with clang
}
int main() {
alignas(sizeof(B<int>)) char buff[sizeof(B<int>)];
B<int>* p = new (buff) B<int>;
foo(p);
}
gcc and msvc compile this just fine. However, clang refuses:
test1.cpp:11:6: error: no member named 'B' in 'A<int, int>'
x->~B<T>();
^
test1.cpp:17:2: note: in instantiation of function template
specialization 'foo<int>' requested here
foo(p);
^
1 error generated.
Who is right? And if clang, then how to write an explicit B<T>
destructor call without relying on how B<T> happens to be defined?
[toc] | [next] | [standalone]
| From | "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> |
|---|---|
| Date | 2020-01-23 11:26 +0100 |
| Message-ID | <r0bsc1$jsa$1@dont-email.me> |
| In reply to | #71515 |
On 22.01.2020 16:01, Paavo Helde wrote:
> Please consider:
>
> #include <new>
>
> template <typename T, typename U>
> class A {};
>
> template <typename T>
> using B = A<T, int>;
>
> template <typename T>
> void foo(B<T>* x) {
> x->~B<T>(); // this line failing with clang
> }
>
> int main() {
> alignas(sizeof(B<int>)) char buff[sizeof(B<int>)];
> B<int>* p = new (buff) B<int>;
> foo(p);
> }
>
> gcc and msvc compile this just fine. However, clang refuses:
>
> test1.cpp:11:6: error: no member named 'B' in 'A<int, int>'
> x->~B<T>();
> ^
> test1.cpp:17:2: note: in instantiation of function template
> specialization 'foo<int>' requested here
> foo(p);
> ^
> 1 error generated.
>
> Who is right? And if clang, then how to write an explicit B<T>
> destructor call without relying on how B<T> happens to be defined?
C++17 §10.1.7.2/1 defines the /type-name/ after `~` as one of
class-name
enum-name
typedef-name
simple-template-id
This suggests that no matter how /simple-template-id/ turns out a fix
can be to use a /typedef-name/.
§17.2/1 defines /simple-template-id/ as (transcribed to typewriter-ish)
template-name `<` template-argument-list OPTIONAL `>`
The question is then whether your template alias `B` is a
/template-name/. The very same paragraph defines /template-name/
syntactically as
identifier
It then explains (in a non-normative note plus in normative text in
paragraph 3) that it's the name lookup that determines if a name is a
/template-name/. I fail to find that. However, §17.5.7 states that
An alias template is a name for a family of types. The name of the
alias template is a /template-name/.
So this is a bug in dang.
Workaround probably as mentioned above.
- Alf
[toc] | [prev] | [next] | [standalone]
| From | Paavo Helde <myfirstname@osa.pri.ee> |
|---|---|
| Date | 2020-01-23 13:09 +0200 |
| Message-ID | <r0busk$24i$1@dont-email.me> |
| In reply to | #71530 |
On 23.01.2020 12:26, Alf P. Steinbach wrote:
> On 22.01.2020 16:01, Paavo Helde wrote:
>> Please consider:
>>
>> #include <new>
>>
>> template <typename T, typename U>
>> class A {};
>>
>> template <typename T>
>> using B = A<T, int>;
>>
>> template <typename T>
>> void foo(B<T>* x) {
>> x->~B<T>(); // this line failing with clang
>> }
>>
>> int main() {
>> alignas(sizeof(B<int>)) char buff[sizeof(B<int>)];
>> B<int>* p = new (buff) B<int>;
>> foo(p);
>> }
>>
>> gcc and msvc compile this just fine. However, clang refuses:
>>
>> test1.cpp:11:6: error: no member named 'B' in 'A<int, int>'
>> x->~B<T>();
>> ^
>> test1.cpp:17:2: note: in instantiation of function template
>> specialization 'foo<int>' requested here
>> foo(p);
>> ^
>> 1 error generated.
>>
>> Who is right? And if clang, then how to write an explicit B<T>
>> destructor call without relying on how B<T> happens to be defined?
>
> C++17 §10.1.7.2/1 defines the /type-name/ after `~` as one of
>
> class-name
> enum-name
> typedef-name
> simple-template-id
>
> This suggests that no matter how /simple-template-id/ turns out a fix
> can be to use a /typedef-name/.
>
> §17.2/1 defines /simple-template-id/ as (transcribed to typewriter-ish)
>
> template-name `<` template-argument-list OPTIONAL `>`
>
> The question is then whether your template alias `B` is a
> /template-name/. The very same paragraph defines /template-name/
> syntactically as
>
> identifier
>
> It then explains (in a non-normative note plus in normative text in
> paragraph 3) that it's the name lookup that determines if a name is a
> /template-name/. I fail to find that. However, §17.5.7 states that
>
> An alias template is a name for a family of types. The name of the
> alias template is a /template-name/.
>
> So this is a bug in dang.
>
> Workaround probably as mentioned above.
Thanks! The typedef workaround indeed seems to work:
template <typename T>
void foo(B<T>* x) {
typedef B<T> B_t;
x->~B_t();
}
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2020-01-27 01:40 -0800 |
| Message-ID | <86zhe9grv3.fsf@linuxsc.com> |
| In reply to | #71531 |
Paavo Helde <myfirstname@osa.pri.ee> writes:
> [problems with x->~B<T>().]
>
> Thanks! The typedef workaround indeed seems to work:
>
> template <typename T>
> void foo(B<T>* x) {
> typedef B<T> B_t;
> x->~B_t();
> }
Alternatively,
template <typename T>
void foo(B<T>* x) {
using B_t = B<T>;
x->~B_t();
}
Don't take this as a complaint, it is simply an unabashed plug
for choosing 'using' over 'typedef' (my own personal preference).
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.c++
csiph-web