Template error without instantiation?

>

Hey folks,
Can you help check which compiler behaves correctly here? To my
untrained mind it seems to be a clang issue but seems too basic to have
been missed unintentionally?

Regards,
Ramneek

x- start -x
class A {};

class B {};

void myfun(A& myexp) {
}

template <typename T>
void mytest(const B &value)
{
myfun(A(value));
}

The behavior of both compilers is consistent with the standard.

This template has no valid instantiation; there is no type T which will allow
an A to be constructed from a const l-value of type B. A template with no valid
instantiation is ill-formed with no diagnostic required (unless instantiated, of
course).

Clang is somewhat more aggressive than GCC about diagnosing errors within
templates at definition time rather than at instantiation time.

template <typename T>
void mytest(const T &value)
{
myfun(A(value));
}

This template does have a valid instantiation: for example, T=A. Therefore it
is not ill-formed.

John.

Thanks John.

Making small immaterial adjustments to code:

x--start--x

class A {};

class B {};

void THIS_IS_AN_ERROR(A& myexp) {
}

template <typename T>
void mytest(const B &value)
{
   THIS_IS_AN_ERROR(A(value));
}

template <typename T>
void mytest(const T &value)
{
   //Do something useful, ignore what we had here earlier
}

x--end--x

It's a case of template specialization where I would like the compiler
to throw an error if B is being passed to mytest.
If not I would like it to do the *useful thing*.

Could you please point me to where in the standard document does it say
that compiler can reject a template if it has no valid instantiation,
without actually being asked to instantiate it?

Regards.

Could you please point me to where in the standard document does it say
that compiler can reject a template if it has no valid instantiation,
without actually being asked to instantiate it?

I'm not John, but the relevant paragraph seems to be 14.6p8:

"Knowing which names are type names allows the syntax of every
template to be checked. No diagnostic shall be issued for a template
for which a valid specialization can be generated. If no valid
specialization can be generated for a template, and that template is
not instantiated, the template is ill-formed, no diagnostic required.
If every valid specialization of a variadic template requires an empty
template parameter pack, the template is ill-formed, no diagnostic
required. If a type used in a non-dependent name is incomplete at the
point at which a template is defined but is complete at the point at
which an instantiation is done, and if the completeness of that type
affects whether or not the program is well-formed or affects the
semantics of the program, the program is ill-formed; no diagnostic is
required..."

-Stephen

Just drop the mytest overload for B and drop this in the generic version:

static_assert(!std::is_same<T, B>::value, "Don't instantiate with B.");

Sebastian