Explicit instantiation of class template with deleted members

64 views
Skip to first unread message

Andrzej Krzemieński

unread,
Oct 11, 2016, 4:51:56 AM10/11/16
to ISO C++ Standard - Discussion
Hi All,
Is the following explicit class template instantiation well-formed?:

template <typename I>
class Ratio
{
public:
   
Ratio (I, I  = 1) {};
   
Ratio (double, double = 1.0) = delete;
};

template class Ratio<int>;

The second constructor is neither inherited, nor is it a template, so as per [temp.explicit]/8, it should be instantiated. Is such instantiation equivalent to being "used" in the sense provided by [dcl.fct.def.delete]/2? ("A program that refers to a deleted function implicitly or explicitly, other than to declare it, is ill-formed.")

GCC and Clang accept, it, but I cannot find a place in the Standard to support it.

Regards,
&rzej;

Richard Smith

unread,
Oct 11, 2016, 12:54:42 PM10/11/16
to std-dis...@isocpp.org
On 11 Oct 2016 1:52 am, "Andrzej Krzemieński" <akrz...@gmail.com> wrote:
Hi All,
Is the following explicit class template instantiation well-formed?:

template <typename I>
class Ratio
{
public:
   
Ratio (I, I  = 1) {};
   
Ratio (double, double = 1.0) = delete;
};

template class Ratio<int>;

The second constructor is neither inherited, nor is it a template, so as per [temp.explicit]/8, it should be instantiated. Is such instantiation equivalent to being "used" in the sense provided by [dcl.fct.def.delete]/2? ("A program that refers to a deleted function implicitly or explicitly, other than to declare it, is ill-formed.")

The only reference to the function is the declaration generated by the instantiation. So the program arguably didn't refer to the function in any way other than to declare it.

GCC and Clang accept, it, but I cannot find a place in the Standard to support it.

Regards,
&rzej;

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+unsubscribe@isocpp.org.
To post to this group, send email to std-dis...@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.

Andrzej Krzemienski

unread,
Oct 11, 2016, 2:35:37 PM10/11/16
to std-dis...@isocpp.org
2016-10-11 18:54 GMT+02:00 Richard Smith <ric...@metafoo.co.uk>:
On 11 Oct 2016 1:52 am, "Andrzej Krzemieński" <akrz...@gmail.com> wrote:
Hi All,
Is the following explicit class template instantiation well-formed?:

template <typename I>
class Ratio
{
public:
   
Ratio (I, I  = 1) {};
   
Ratio (double, double = 1.0) = delete;
};

template class Ratio<int>;

The second constructor is neither inherited, nor is it a template, so as per [temp.explicit]/8, it should be instantiated. Is such instantiation equivalent to being "used" in the sense provided by [dcl.fct.def.delete]/2? ("A program that refers to a deleted function implicitly or explicitly, other than to declare it, is ill-formed.")

The only reference to the function is the declaration generated by the instantiation. So the program arguably didn't refer to the function in any way other than to declare it.

Thanks for the response. Still, I feel a bit uncomfortable about this explanation. the explicit class template declaration did refer to a deleted function *indirectly*: I knew that the second deleted constructor is one of its non-inherited, non-template member functions, and I requested that its definition be instantiated. (Whatever it means for a deleted definition to be instantiated). I did not mention the function (class) name explicitly, but is it enough? The word "implicitly" in [dcl.fct.def.delete]/2 sounds very open to interpretation.

Regards,
&rzej;




Robert Haberlach

unread,
Oct 11, 2016, 3:59:19 PM10/11/16
to std-dis...@isocpp.org


On 10/11/2016 07:35 PM, Andrzej Krzemienski wrote:
>
>
> 2016-10-11 18:54 GMT+02:00 Richard Smith <ric...@metafoo.co.uk <mailto:ric...@metafoo.co.uk>>:
>
> On 11 Oct 2016 1:52 am, "Andrzej Krzemieński" <akrz...@gmail.com <mailto:akrz...@gmail.com>> wrote:
>
> Hi All,
> Is the following explicit class template instantiation well-formed?:
>
> |
> template<typenameI>
> classRatio
> {
> public:
> Ratio(I,I =1){};
> Ratio(double,double=1.0)=delete;
> };
>
> templateclassRatio<int>;
> |
>
> The second constructor is neither inherited, nor is it a template, so as per [temp.explicit]/8, it should be instantiated. Is such
> instantiation equivalent to being "used" in the sense provided by [dcl.fct.def.delete]/2? ("A program that refers to a deleted function
> implicitly or explicitly, other than to declare it, is ill-formed.")
>
>
> The only reference to the function is the declaration generated by the instantiation. So the program arguably didn't refer to the function in any
> way other than to declare it.
>
>
> Thanks for the response. Still, I feel a bit uncomfortable about this explanation. the explicit class template declaration did refer to a deleted
> function *indirectly*: I knew that the second deleted constructor is one of its non-inherited, non-template member functions, and I requested that its
> definition be instantiated. (Whatever it means for a deleted definition to be instantiated). I did not mention the function (class) name explicitly,
> but is it enough? The word "implicitly" in [dcl.fct.def.delete]/2 sounds very open to interpretation.

Precisely: and is an interpretation sensible if it disallows defining templated member entities as deleted? No implementation thinks so, and neither
do we.

>
> Regards,
> &rzej;
>
>
>
>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to std-discussio...@isocpp.org
> <mailto:std-discussio...@isocpp.org>.
> To post to this group, send email to std-dis...@isocpp.org <mailto:std-dis...@isocpp.org>.

Johannes Schaub

unread,
Oct 11, 2016, 4:32:25 PM10/11/16
to std-dis...@isocpp.org

Declarations are exempt from the "refering to a deleted function is illformed".

Anyway, this does not even require an explicit instantiation. Merely saying

   Ratio<int> r(5)

Refers to the deleted constructor in order to declare it as a member of "Ratio<int>".

I don't have the spec here, but I believe that you could argue that the constructor is not even deleted yet at that point and at the point that it is explicitly instantiated. Because the deletion is the function's definition, and when the explicit instantiation of the function definition (the = delete part) is performed, the function is not yet deleted. Only afterwards.

> --
>
> ---
> You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.

> To unsubscribe from this group and stop receiving emails from it, send an email to std-discussio...@isocpp.org.

Matthew Woehlke

unread,
Oct 12, 2016, 3:26:40 PM10/12/16
to std-dis...@isocpp.org
On 2016-10-11 04:51, Andrzej Krzemieński wrote:
> Is the following explicit class template instantiation well-formed?:
>
> template <typename I>
> class Ratio
> {
> public:
> Ratio (I, I = 1) {};
> Ratio (double, double = 1.0) = delete;
> };
>
> template class Ratio<int>;
>
> The second constructor is neither inherited, nor is it a template, so as
> per [temp.explicit]/8, it should be instantiated. Is such instantiation
> equivalent to being "used" in the sense provided by [dcl.fct.def.delete]/2?
> ("A program that refers to a deleted function implicitly or explicitly,
> other than to declare it, is ill-formed.")

No.

I'm pretty sure "refers to" here means (at least for practical purposes)
"tries to execute or take the address of".

You aren't doing that. You're instantiating a class that has a deleted
function.

Consider this example instead:

class IntRatio
{
public:
Ratio(int, int = 1) {};
Ratio(double, double = 1.0) = delete;
};

There is nothing whatsoever wrong with this class. Why would you expect
the class being a template class to change things? The instantiation
`Ratio<int>` is not magically different from `IntRatio`; not anyway
w.r.t. the deleted function.

--
Matthew

Andrzej Krzemienski

unread,
Oct 13, 2016, 2:44:48 AM10/13/16
to std-dis...@isocpp.org
:) Now, this is really convincing. Thank you.

Reply all
Reply to author
Forward
0 new messages