From: Daniel Krügler on
On 29 Jul., 15:48, Daniel Kr�gler <daniel.krueg...(a)googlemail.com>
wrote:
> ad c) I agree that the Standard in general includes the instantiation
> of definitions *when* they are required to exist and *when* they
> are available. But there are two special situations, when only non-
> defining declarations are supposed to be instantiated:
>
> 1) When a class template is implicitly instantiated, only the
> declarations
> of the member functions are instantiated, see 14.7.1/1:
>
> "[..] The implicit instantiation of a class template specialization
> causes
> the implicit instantiation of the declarations, but not of the
> definitions or
> default arguments, of the class member functions, member classes,
> static data members and member templates; and it causes the implicit
> instantiation of the definitions of member anonymous unions. [..] "
>
> [I'm not sure whether the requirement of "implicitly instantiating
> the declarations of member templates" is correct - it looks dubious
> to me, because they still don't have any types or values available
> to make this possible.]

I believe that I'm misinterpreting the normative wording with
my comment:

The above paragraphs says what we expect: No definitions
or default arguments of the members (including the member
templates) are to be instantiated. When I read it during
my quotation I interpreted it (wrongly) to say that the
declarations of the member templates will be instantiated.

This correction should not influence anything else from the
previous posting.

- Daniel


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Nikolay Ivchenkov on
On 29 Jul, 17:48, Daniel Kr�gler <daniel.krueg...(a)googlemail.com>
wrote:
>
> ad c) I agree that the Standard in general includes the instantiation
> of definitions *when* they are required to exist and *when* they
> are available.

#include <iostream>

int n = 0;

template <class T>
struct B
{
B()
{
if (n)
f();
// pure function call
// (see the suggested resolution for core issue 230)
}
virtual void f() = 0;
};

template <class T>
void B<T>::f()
{ std::cout << "B<T>::f()\n"; }

struct D : B<int>
{
D()
{ static_cast<B<int> &>(*this).f(); }
void f()
{ std::cout << "D::f()\n"; }
};

int main()
{
std::cin >> n;
D();
}

A definition of B<int>::f is not required to be exist. Thus, we can't
apply 14.7.1/2

"Unless a function template specialization has been explicitly
instantiated or explicitly specialized, the function template
specialization is implicitly instantiated when the specialization is
referenced in a context that requires a function definition to exist."

Must the definition of B<int>::f be instantiated?


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Nikolay Ivchenkov on
On 30 Jul, 19:18, Daniel Kr�gler <daniel.krueg...(a)googlemail.com>
wrote:
>
> Even though B<int>::f is not required to exist in any general program

Did you mean "_a definition of_ B<int>::f is not required to exist"?

> it is required to exist in this particular program, because it is
> still used
> in the sense of the *general* requirements specified in 3.2/2:
>
> "An expression is potentially evaluated unless it is an unevaluated
> operand (Clause 5) or a subexpression thereof. A variable or non-
> overloaded function whose name appears as a potentially-evaluated
> expression is used unless it is an object that satisfies the
> requirements for appearing in a constant expression (5.19)
> and the lvalue-to-rvalue conversion (4.1) is immediately applied.[..]"
>
> The example invokes the constructor of B as part of a potentially
> evaluated expression. Note that the refining sentence:
>
> "A virtual member function is used if it is not pure."
>
> does not declare a pure virtual function as *unused*, it only declares
> *any* non-pure virtual function as *used*.

I can't accept this explanation. Lets consider more simple example:

struct AbstractBase
{
virtual void f() = 0;
};

struct Derived : AbstractBase
{
void f() { /*...*/ }
};

void g(AbstractBase &x)
{
x.f();
}

int main()
{
Derived d;
g(d);
}

If the function AbstractBase::f is used, we shall apply 3.2/3:

"Every program shall contain exactly one definition of every non-
inline function or object that is used in that
program; no diagnostic required."

So, the program above would be ill-formed and in general undefined
pure virtual functions would be almost useless? Then the wording

"A pure virtual function need be defined only if explicitly called
with the qualified-id syntax (5.1)." (10.4/2)

is wrong?

> This is a big difference,
> because it does not make the former requirements invalid.

In any case the specification is bad.

I can point out another issue:

namespace N
{
struct A {};
void f(A, int) { /*...*/ }
}

void f(N::A, long) { /*...*/ }

int main()
{
f(N::A(), 0);
}

Are functions N::f and ::f overloaded? No? Then which functions are
used according to literal interpretation of 3.2/2? Both? :-)


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]