730 lines
19 KiB
C++
730 lines
19 KiB
C++
// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify -Wno-c++2a-extensions
|
|
// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify
|
|
|
|
template <bool b, auto val> struct enable_ifv {};
|
|
|
|
template <auto val> struct enable_ifv<true, val> {
|
|
static constexpr auto value = val;
|
|
};
|
|
|
|
template <typename T1, typename T2> struct is_same {
|
|
static constexpr bool value = false;
|
|
};
|
|
|
|
template <typename T> struct is_same<T, T> {
|
|
static constexpr bool value = true;
|
|
};
|
|
|
|
namespace special_cases
|
|
{
|
|
|
|
template<int a>
|
|
struct A {
|
|
// expected-note@-1+ {{candidate constructor}}
|
|
explicit(1 << a)
|
|
// expected-note@-1 {{negative shift count -1}}
|
|
// expected-error@-2 {{explicit specifier argument is not a constant expression}}
|
|
A(int);
|
|
};
|
|
|
|
A<-1> a(0);
|
|
// expected-error@-1 {{no matching constructor}}
|
|
// expected-note@-2 {{in instantiation of template class}}
|
|
|
|
template<int a>
|
|
struct B {
|
|
explicit(b)
|
|
// expected-error@-1 {{use of undeclared identifier}}
|
|
B(int);
|
|
};
|
|
|
|
template<int a>
|
|
struct B1 {
|
|
explicit(a +)
|
|
// expected-error@-1 {{expected expression}}
|
|
B1(int);
|
|
};
|
|
|
|
struct B2 {
|
|
explicit(false) explicit
|
|
B2(int);
|
|
// expected-error@-2 {{duplicate 'explicit' declaration specifier}}
|
|
};
|
|
|
|
template<int a>
|
|
struct C {
|
|
// expected-note@-1 {{candidate constructor}} expected-note@-1 {{candidate constructor}}
|
|
// expected-note@-2 {{candidate constructor}} expected-note@-2 {{candidate constructor}}
|
|
explicit(a == 0)
|
|
C(int), // expected-note 2{{not a candidate}}
|
|
C(double); // expected-note 2{{not a candidate}}
|
|
};
|
|
|
|
C<0> c0 = 0.0; // expected-error {{no viable conversion}}
|
|
C<0> c1 = 0; // expected-error {{no viable conversion}}
|
|
C<1> c2 = 0.0;
|
|
C<1> c3 = 0;
|
|
|
|
explicit(false) void f(int);// expected-error {{'explicit' can only be specified inside the class definition}}
|
|
|
|
struct D {
|
|
explicit(false) void f(int);// expected-error {{'explicit' can only be applied to a constructor or conversion function}}
|
|
};
|
|
|
|
template <typename T> struct E {
|
|
// expected-note@-1+ {{candidate constructor}}
|
|
explicit((T{}, false))
|
|
// expected-error@-1 {{illegal initializer type 'void'}}
|
|
E(int);
|
|
};
|
|
|
|
E<void> e = 1;
|
|
// expected-error@-1 {{no viable conversion}}
|
|
// expected-note@-2 {{in instantiation of}}
|
|
|
|
}
|
|
|
|
namespace trailling_object {
|
|
|
|
template<bool b>
|
|
struct B {
|
|
explicit(b) B(int) {}
|
|
};
|
|
|
|
template<bool b>
|
|
struct A : B<b> {
|
|
explicit(b) A(int) : B<b>(0) {}
|
|
};
|
|
|
|
A<true> a(0);
|
|
|
|
}
|
|
|
|
namespace constructor1 {
|
|
|
|
template<bool b>
|
|
struct A {
|
|
// expected-note@-1+ {{candidate constructor}}
|
|
// expected-note@-2+ {{candidate function}}
|
|
explicit(b) A(int, int = 0); // expected-note {{not a candidate}}
|
|
// expected-note@-1+ {{explicit constructor declared here}}
|
|
};
|
|
|
|
template<bool b>
|
|
A<b>::A(int, int) {}
|
|
|
|
void f()
|
|
{
|
|
A<true> a0 = 0; // expected-error {{no viable conversion}}
|
|
A<true> a1( 0);
|
|
A<true> && a2 = 0;// expected-error {{could not bind}}
|
|
A<true> && a3( 0);// expected-error {{could not bind}}
|
|
A<true> a4{ 0};
|
|
A<true> && a5 = { 0};// expected-error {{chosen constructor is explicit}}
|
|
A<true> && a6{ 0};
|
|
A<true> a7 = { 0}; // expected-error {{chosen constructor is explicit in copy-initialization}}
|
|
|
|
a0 = 0; // expected-error {{no viable overloaded '='}}
|
|
a1 = { 0}; // expected-error {{no viable overloaded '='}}
|
|
a2 = A<true>( 0);
|
|
a3 = A<true>{ 0};
|
|
|
|
A<false> c0 = ((short)0);
|
|
A<false> c1( ((short)0));
|
|
A<false> && c2 = ((short)0);
|
|
A<false> && c3( ((short)0));
|
|
A<false> c4{ ((short)0)};
|
|
A<false> && c5 = { ((short)0)};
|
|
A<false> && c6{ ((short)0)};
|
|
|
|
A<true> d1( 0, 0);
|
|
A<true> d2{ 0, 0};
|
|
A<true> d3 = { 0, 0}; // expected-error {{chosen constructor is explicit in copy-initialization}}
|
|
|
|
d1 = { 0, 0}; // expected-error {{no viable overloaded '='}}
|
|
d2 = A<true>( 0, 0);
|
|
d3 = A<true>{ 0, 0};
|
|
}
|
|
}
|
|
|
|
namespace constructor2 {
|
|
|
|
template<bool a, typename T1>
|
|
struct A {
|
|
// expected-note@-1 {{candidate constructor}} expected-note@-1 {{candidate constructor}}
|
|
// expected-note@-2 {{candidate constructor}} expected-note@-2 {{candidate constructor}}
|
|
template<typename T2>
|
|
explicit(a ^ is_same<T1, T2>::value)
|
|
A(T2) {}
|
|
// expected-note@-1+ {{explicit constructor declared here}}
|
|
// expected-note@-2+ {{not a candidate}}
|
|
};
|
|
|
|
A<true, int> a0 = 0.0; // expected-error {{no viable conversion}}
|
|
A<true, int> a1( 0.0);
|
|
A<true, int> && a2 = 0.0;// expected-error {{could not bind}}
|
|
A<true, int> && a3( 0.0);// expected-error {{could not bind}}
|
|
A<true, int> a4{ 0.0};
|
|
A<true, int> && a5 = { 0.0};// expected-error {{chosen constructor is explicit}}
|
|
A<true, int> && a6{ 0.0};
|
|
A<true, int> a7 = { 0.0}; // expected-error {{chosen constructor is explicit in copy-initialization}}
|
|
|
|
A<true, int> b0 = 0;
|
|
A<true, int> b1( 0);
|
|
A<true, int> && b2 = 0;
|
|
A<true, int> && b3( 0);
|
|
A<true, int> b4{ 0};
|
|
A<true, int> && b5 = { 0};
|
|
A<true, int> && b6{ 0};
|
|
A<true, int> b7 = { 0};
|
|
|
|
A<true, double> c0 = 0; // expected-error {{no viable conversion}}
|
|
A<true, double> c1( 0);
|
|
A<true, double> && c2 = 0;// expected-error {{could not bind}}
|
|
A<true, double> && c3( 0);// expected-error {{could not bind}}
|
|
A<true, double> c4{ 0};
|
|
A<true, double> && c5 = { 0};// expected-error {{chosen constructor is explicit}}
|
|
A<true, double> && c6{ 0};
|
|
A<true, double> c7 = { 0}; // expected-error {{chosen constructor is explicit in copy-initialization}}
|
|
|
|
}
|
|
|
|
namespace constructor_sfinae {
|
|
|
|
template<bool a>
|
|
struct A {
|
|
// expected-note@-1+ {{candidate constructor}}
|
|
template<typename T>
|
|
explicit(enable_ifv<is_same<int, T>::value, a>::value)
|
|
A(T) {}
|
|
// expected-note@-1+ {{substitution failure}}
|
|
// expected-note@-2 {{not a candidate}}
|
|
// expected-note@-3 {{explicit constructor declared here}}
|
|
template<typename T, bool c = true>
|
|
explicit(enable_ifv<is_same<bool, T>::value, a>::value)
|
|
A(T) {}
|
|
// expected-note@-1+ {{substitution failure}}
|
|
// expected-note@-2 {{not a candidate}}
|
|
// expected-note@-3 {{explicit constructor declared here}}
|
|
};
|
|
|
|
A<true> a0 = 0.0; // expected-error {{no viable conversion}}
|
|
A<true> a1( 0.0); // expected-error {{no matching constructor}}
|
|
A<true> a4{ 0.0}; // expected-error {{no matching constructor}}
|
|
A<true> a7 = { 0.0}; // expected-error {{no matching constructor}}
|
|
|
|
A<true> b0 = 0; // expected-error {{no viable conversion}}
|
|
A<true> b1( 0);
|
|
A<true> b4{ 0};
|
|
A<true> b7 = { 0}; // expected-error {{chosen constructor is explicit}}
|
|
|
|
A<false> c0 = 0;
|
|
A<false> c1( 0);
|
|
A<false> c4{ 0};
|
|
A<false> c7 = { 0};
|
|
|
|
A<true> d0 = true; // expected-error {{no viable conversion}}
|
|
A<true> d1( true);
|
|
A<true> d4{ true};
|
|
A<true> d7 = { true}; // expected-error {{chosen constructor is explicit}}
|
|
|
|
}
|
|
|
|
namespace conversion {
|
|
|
|
template<bool a>
|
|
struct A {
|
|
explicit(a) operator int (); // expected-note+ {{not a candidate}}
|
|
};
|
|
|
|
template<bool a>
|
|
A<a>::operator int() {
|
|
return 0;
|
|
}
|
|
|
|
A<true> A_true;
|
|
A<false> A_false;
|
|
|
|
int ai0 = A<true>(); // expected-error {{no viable conversion}}
|
|
const int& ai1 = A<true>(); // expected-error {{no viable conversion}}
|
|
int&& ai3 = A<true>(); // expected-error {{no viable conversion}}
|
|
int ai4 = A_true; // expected-error {{no viable conversion}}
|
|
const int& ai5 = A_true; // expected-error {{no viable conversion}}
|
|
|
|
int ai01 = {A<true>()}; // expected-error {{no viable conversion}}
|
|
const int& ai11 = {A<true>()}; // expected-error {{no viable conversion}}
|
|
int&& ai31 = {A<true>()}; // expected-error {{no viable conversion}}
|
|
int ai41 = {A_true}; // expected-error {{no viable conversion}}
|
|
const int& ai51 = {A_true}; // expected-error {{no viable conversion}}
|
|
|
|
int ae0(A<true>());
|
|
const int& ae1(A<true>());
|
|
int&& ae3(A<true>());
|
|
int ae4(A_true);
|
|
const int& ae5(A_true);
|
|
|
|
int bi0 = A<false>();
|
|
const int& bi1 = A<false>();
|
|
int&& bi3 = A<false>();
|
|
int bi4 = A_false;
|
|
const int& bi5 = A_false;
|
|
|
|
int bi01 = {A<false>()};
|
|
const int& bi11 = {A<false>()};
|
|
int&& bi31 = {A<false>()};
|
|
int bi41 = {A_false};
|
|
const int& bi51 = {A_false};
|
|
|
|
int be0(A<true>());
|
|
const int& be1(A<true>());
|
|
int&& be3(A<true>());
|
|
int be4(A_true);
|
|
const int& be5(A_true);
|
|
|
|
}
|
|
|
|
namespace conversion2 {
|
|
|
|
struct B {};
|
|
// expected-note@-1+ {{candidate constructor}}
|
|
template<bool a>
|
|
struct A {
|
|
template<typename T2>
|
|
explicit(enable_ifv<is_same<B, T2>::value, a>::value)
|
|
operator T2() { return T2(); };
|
|
// expected-note@-1+ {{substitution failure}}
|
|
// expected-note@-2+ {{not a candidate}}
|
|
};
|
|
|
|
A<false> A_false;
|
|
A<true> A_true;
|
|
|
|
int ai0 = A<true>(); // expected-error {{no viable conversion}}
|
|
const int& ai1 = A<true>(); // expected-error {{no viable conversion}}
|
|
int&& ai3 = A<true>(); // expected-error {{no viable conversion}}
|
|
int ai4 = A_false; // expected-error {{no viable conversion}}
|
|
const int& ai5 = A_false; // expected-error {{no viable conversion}}
|
|
|
|
int ae0{A<true>()}; // expected-error {{no viable conversion}}
|
|
const int& ae1{A<true>()}; // expected-error {{no viable conversion}}
|
|
int&& ae3{A<true>()}; // expected-error {{no viable conversion}}
|
|
int ae4{A_true}; // expected-error {{no viable conversion}}
|
|
const int& ae5{A_true}; // expected-error {{no viable conversion}}
|
|
|
|
int ap0((A<true>())); // expected-error {{no viable conversion}}
|
|
const int& ap1((A<true>())); // expected-error {{no viable conversion}}
|
|
int&& ap3((A<true>())); // expected-error {{no viable conversion}}
|
|
int ap4(A_true); // expected-error {{no viable conversion}}
|
|
const int& ap5(A_true); // expected-error {{no viable conversion}}
|
|
|
|
B b0 = A<true>(); // expected-error {{no viable conversion}}
|
|
const B & b1 = A<true>(); // expected-error {{no viable conversion}}
|
|
B && b3 = A<true>(); // expected-error {{no viable conversion}}
|
|
B b4 = A_true; // expected-error {{no viable conversion}}
|
|
const B & b5 = A_true; // expected-error {{no viable conversion}}
|
|
|
|
B be0(A<true>());
|
|
const B& be1(A<true>());
|
|
B&& be3(A<true>());
|
|
B be4(A_true);
|
|
const B& be5(A_true);
|
|
|
|
B c0 = A<false>();
|
|
const B & c1 = A<false>();
|
|
B && c3 = A<false>();
|
|
B c4 = A_false;
|
|
const B & c5 = A_false;
|
|
|
|
}
|
|
|
|
namespace parameter_pack {
|
|
|
|
template<typename T>
|
|
struct A {
|
|
// expected-note@-1+ {{candidate constructor}}
|
|
// expected-note@-2+ {{candidate function}}
|
|
template<typename ... Ts>
|
|
explicit((is_same<T, Ts>::value && ...))
|
|
A(Ts...);
|
|
// expected-note@-1 {{not a candidate}}
|
|
// expected-note@-2 {{explicit constructor}}
|
|
};
|
|
|
|
template<typename T>
|
|
template<typename ... Ts>
|
|
A<T>::A(Ts ...) {}
|
|
|
|
void f() {
|
|
|
|
A<int> a0 = 0; // expected-error {{no viable conversion}}
|
|
A<int> a1( 0, 1);
|
|
A<int> a2{ 0, 1};
|
|
A<int> a3 = { 0, 1}; // expected-error {{chosen constructor is explicit}}
|
|
|
|
a1 = 0; // expected-error {{no viable overloaded '='}}
|
|
a2 = { 0, 1}; // expected-error {{no viable overloaded '='}}
|
|
|
|
A<double> b0 = 0;
|
|
A<double> b1( 0, 1);
|
|
A<double> b2{ 0, 1};
|
|
A<double> b3 = { 0, 1};
|
|
|
|
b1 = 0;
|
|
b2 = { 0, 1};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
namespace deduction_guide {
|
|
|
|
template<bool b>
|
|
struct B {};
|
|
|
|
B<true> b_true;
|
|
B<false> b_false;
|
|
|
|
template<typename T>
|
|
struct nondeduced
|
|
{
|
|
using type = T;
|
|
};
|
|
|
|
template<typename T1, typename T2, bool b>
|
|
struct A {
|
|
// expected-note@-1+ {{candidate function}}
|
|
explicit(false)
|
|
A(typename nondeduced<T1>::type, typename nondeduced<T2>::type, typename nondeduced<B<b>>::type) {}
|
|
// expected-note@-1+ {{candidate template ignored}}
|
|
};
|
|
|
|
template<typename T1, typename T2, bool b>
|
|
explicit(enable_ifv<is_same<T1, T2>::value, b>::value)
|
|
A(T1, T2, B<b>) -> A<T1, T2, b>;
|
|
// expected-note@-1+ {{explicit deduction guide declared here}}
|
|
// expected-note@-2+ {{candidate template ignored}}
|
|
void f() {
|
|
|
|
A a0( 0.0, 1, b_true); // expected-error {{no viable constructor or deduction guide}}
|
|
A a1{ 0.0, 1, b_true}; // expected-error {{no viable constructor or deduction guide}}
|
|
A a2 = { 0.0, 1, b_true}; // expected-error {{no viable constructor or deduction guide}}
|
|
auto a4 = A( 0.0, 1, b_true); // expected-error {{no viable constructor or deduction guide}}
|
|
auto a5 = A{ 0.0, 1, b_true}; // expected-error {{no viable constructor or deduction guide}}
|
|
|
|
A b0( 0, 1, b_true);
|
|
A b1{ 0, 1, b_true};
|
|
A b2 = { 0, 1, b_true}; // expected-error {{explicit deduction guide for copy-list-initialization}}
|
|
auto b4 = A( 0, 1, b_true);
|
|
auto b5 = A{ 0, 1, b_true};
|
|
b0 = { 0, 1, b_false}; // expected-error {{no viable overloaded '='}}
|
|
|
|
A c0( 0, 1, b_false);
|
|
A c1{ 0, 1, b_false};
|
|
A c2 = { 0, 1, b_false};
|
|
auto c4 = A( 0, 1, b_false);
|
|
auto c5 = A{ 0, 1, b_false};
|
|
c2 = { 0, 1, b_false};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
namespace test8 {
|
|
|
|
template<bool b>
|
|
struct A {
|
|
//expected-note@-1+ {{candidate function}}
|
|
template<typename T1, typename T2>
|
|
explicit(b)
|
|
A(T1, T2) {}
|
|
//expected-note@-1 {{explicit constructor declared here}}
|
|
};
|
|
|
|
template<typename T1, typename T2>
|
|
explicit(!is_same<T1, int>::value)
|
|
A(T1, T2) -> A<!is_same<int, T2>::value>;
|
|
// expected-note@-1+ {{explicit deduction guide declared here}}
|
|
|
|
template<bool b>
|
|
A<b> v();
|
|
|
|
void f() {
|
|
|
|
A a0( 0, 1);
|
|
A a1{ 0, 1};
|
|
A a2 = { 0, 1};
|
|
auto a4 = A( 0, 1);
|
|
auto a5 = A{ 0, 1};
|
|
auto a6(v<false>());
|
|
a6 = { 0, 1};
|
|
|
|
A b0( 0.0, 1);
|
|
A b1{ 0.0, 1};
|
|
A b2 = { 0.0, 1}; // expected-error {{explicit deduction guide for copy-list-initialization}}
|
|
auto b4 = A( 0.0, 1);
|
|
auto b5 = A{ 0.0, 1};
|
|
|
|
A c0( 0, 1.0);
|
|
A c1{ 0, 1.0};
|
|
A c2 = { 0, 1.0}; // expected-error {{chosen constructor is explicit}}
|
|
auto c4 = A( 0, 1.0);
|
|
auto c5 = A{ 0, 1.0};
|
|
auto c6(v<true>());
|
|
c0 = { 0, 1.0}; // expected-error {{no viable overloaded '='}}
|
|
|
|
A d0( 0.0, 1.0);
|
|
A d1{ 0.0, 1.0};
|
|
A d2 = { 0.0, 1.0}; // expected-error {{explicit deduction guide for copy-list-initialization}}
|
|
auto d4 = A( 0.0, 1.0);
|
|
auto d5 = A{ 0.0, 1.0};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
namespace conversion3 {
|
|
|
|
template<bool b>
|
|
struct A {
|
|
explicit(!b) operator int();
|
|
explicit(b) operator bool();
|
|
};
|
|
|
|
template<bool b>
|
|
A<b>::operator bool() { return false; }
|
|
|
|
struct B {
|
|
void f(int);
|
|
void f(bool);
|
|
};
|
|
|
|
void f(A<true> a, B b) {
|
|
b.f(a);
|
|
}
|
|
|
|
void f1(A<false> a, B b) {
|
|
b.f(a);
|
|
}
|
|
|
|
// Taken from 12.3.2p2
|
|
class X { X(); };
|
|
class Y { }; // expected-note+ {{candidate constructor (the implicit}}
|
|
|
|
template<bool b>
|
|
struct Z {
|
|
explicit(b) operator X() const;
|
|
explicit(b) operator Y() const; // expected-note 2{{not a candidate}}
|
|
explicit(b) operator int() const; // expected-note {{not a candidate}}
|
|
};
|
|
|
|
void testExplicit()
|
|
{
|
|
Z<true> z;
|
|
// 13.3.1.4p1 & 8.5p16:
|
|
Y y2 = z; // expected-error {{no viable conversion}}
|
|
Y y2b(z);
|
|
Y y3 = (Y)z;
|
|
Y y4 = Y(z);
|
|
Y y5 = static_cast<Y>(z);
|
|
// 13.3.1.5p1 & 8.5p16:
|
|
int i1 = (int)z;
|
|
int i2 = int(z);
|
|
int i3 = static_cast<int>(z);
|
|
int i4(z);
|
|
// 13.3.1.6p1 & 8.5.3p5:
|
|
const Y& y6 = z; // expected-error {{no viable conversion}}
|
|
const int& y7 = z; // expected-error {{no viable conversion}}
|
|
const Y& y8(z);
|
|
const int& y9(z);
|
|
|
|
// Y is an aggregate, so aggregate-initialization is performed and the
|
|
// conversion function is not considered.
|
|
const Y y10{z}; // expected-error {{excess elements}}
|
|
const Y& y11{z}; // expected-error {{excess elements}} expected-note {{in initialization of temporary}}
|
|
const int& y12{z};
|
|
|
|
// X is not an aggregate, so constructors are considered,
|
|
// per 13.3.3.1/4 & DR1467.
|
|
const X x1{z};
|
|
const X& x2{z};
|
|
}
|
|
|
|
struct tmp {};
|
|
|
|
template<typename T1>
|
|
struct C {
|
|
template<typename T>
|
|
explicit(!is_same<T1, T>::value)
|
|
operator T(); // expected-note+ {{explicit conversion function is not a candidate}}
|
|
};
|
|
|
|
using Bool = C<bool>;
|
|
using Integral = C<int>;
|
|
using Unrelated = C<tmp>;
|
|
|
|
void testBool() {
|
|
Bool b;
|
|
Integral n;
|
|
Unrelated u;
|
|
|
|
(void) (1 + b); // expected-error {{invalid operands to binary expression}}
|
|
(void) (1 + n);
|
|
(void) (1 + u); // expected-error {{invalid operands to binary expression}}
|
|
|
|
// 5.3.1p9:
|
|
(void) (!b);
|
|
(void) (!n);
|
|
(void) (!u);
|
|
|
|
// 5.14p1:
|
|
(void) (b && true);
|
|
(void) (n && true);
|
|
(void) (u && true);
|
|
|
|
// 5.15p1:
|
|
(void) (b || true);
|
|
(void) (n || true);
|
|
(void) (u || true);
|
|
|
|
// 5.16p1:
|
|
(void) (b ? 0 : 1);
|
|
(void) (n ? 0: 1);
|
|
(void) (u ? 0: 1);
|
|
|
|
// // 5.19p5:
|
|
// // TODO: After constexpr has been implemented
|
|
|
|
// 6.4p4:
|
|
if (b) {}
|
|
if (n) {}
|
|
if (u) {}
|
|
|
|
// 6.4.2p2:
|
|
switch (b) {} // expected-error {{statement requires expression of integer type}}
|
|
switch (n) {} // expected-error {{statement requires expression of integer type}}
|
|
switch (u) {} // expected-error {{statement requires expression of integer type}}
|
|
|
|
// 6.5.1:
|
|
while (b) {}
|
|
while (n) {}
|
|
while (u) {}
|
|
|
|
// 6.5.2p1:
|
|
do {} while (b);
|
|
do {} while (n);
|
|
do {} while (u);
|
|
|
|
// 6.5.3:
|
|
for (;b;) {}
|
|
for (;n;) {}
|
|
for (;u;) {}
|
|
|
|
// 13.3.1.5p1:
|
|
bool db1(b);
|
|
bool db2(n);
|
|
bool db3(u);
|
|
int di1(b);
|
|
int di2(n);
|
|
int di3(n);
|
|
const bool &direct_cr1(b);
|
|
const bool &direct_cr2(n);
|
|
const bool &direct_cr3(n);
|
|
const int &direct_cr4(b);
|
|
const int &direct_cr5(n);
|
|
const int &direct_cr6(n);
|
|
bool directList1{b};
|
|
bool directList2{n};
|
|
bool directList3{n};
|
|
int directList4{b};
|
|
int directList5{n};
|
|
int directList6{n};
|
|
const bool &directList_cr1{b};
|
|
const bool &directList_cr2{n};
|
|
const bool &directList_cr3{n};
|
|
const int &directList_cr4{b};
|
|
const int &directList_cr5{n};
|
|
const int &directList_cr6{n};
|
|
bool copy1 = b;
|
|
bool copy2 = n;// expected-error {{no viable conversion}}
|
|
bool copyu2 = u;// expected-error {{no viable conversion}}
|
|
int copy3 = b;// expected-error {{no viable conversion}}
|
|
int copy4 = n;
|
|
int copyu4 = u;// expected-error {{no viable conversion}}
|
|
const bool ©5 = b;
|
|
const bool ©6 = n;// expected-error {{no viable conversion}}
|
|
const bool ©u6 = u;// expected-error {{no viable conversion}}
|
|
const int ©7 = b;// expected-error {{no viable conversion}}
|
|
const int ©8 = n;
|
|
const int ©u8 = u;// expected-error {{no viable conversion}}
|
|
bool copyList1 = {b};
|
|
bool copyList2 = {n};// expected-error {{no viable conversion}}
|
|
bool copyListu2 = {u};// expected-error {{no viable conversion}}
|
|
int copyList3 = {b};// expected-error {{no viable conversion}}
|
|
int copyList4 = {n};
|
|
int copyListu4 = {u};// expected-error {{no viable conversion}}
|
|
const bool ©List5 = {b};
|
|
const bool ©List6 = {n};// expected-error {{no viable conversion}}
|
|
const bool ©Listu6 = {u};// expected-error {{no viable conversion}}
|
|
const int ©List7 = {b};// expected-error {{no viable conversion}}
|
|
const int ©List8 = {n};
|
|
const int ©Listu8 = {u};// expected-error {{no viable conversion}}
|
|
}
|
|
|
|
}
|
|
|
|
namespace deduction_guide2 {
|
|
|
|
template<typename T1 = int, typename T2 = int>
|
|
struct A {
|
|
// expected-note@-1+ {{candidate template ignored}}
|
|
explicit(!is_same<T1, T2>::value)
|
|
A(T1 = 0, T2 = 0) {}
|
|
// expected-note@-1 {{explicit constructor declared here}}
|
|
// expected-note@-2 2{{explicit constructor is not a candidate}}
|
|
};
|
|
|
|
A a0 = 0;
|
|
A a1(0, 0);
|
|
A a2{0, 0};
|
|
A a3 = {0, 0};
|
|
|
|
A b0 = 0.0; // expected-error {{no viable constructor or deduction guide}}
|
|
A b1(0.0, 0.0);
|
|
A b2{0.0, 0.0};
|
|
A b3 = {0.0, 0.0};
|
|
|
|
A b4 = {0.0, 0}; // expected-error {{explicit constructor}}
|
|
|
|
template<typename T1, typename T2>
|
|
explicit A(T1, T2) -> A<T1, T2>;
|
|
// expected-note@-1+ {{explicit deduction guide}}
|
|
|
|
A c0 = 0;
|
|
A c1(0, 0);
|
|
A c2{0, 0};
|
|
A c3 = {0, 0};// expected-error {{explicit deduction guide}}
|
|
|
|
A d0 = 0.0; // expected-error {{no viable constructor or deduction guide}}
|
|
A d1(0, 0);
|
|
A d2{0, 0};
|
|
A d3 = {0.0, 0.0};// expected-error {{explicit deduction guide}}
|
|
|
|
}
|
|
|
|
namespace PR42980 {
|
|
using size_t = decltype(sizeof(0));
|
|
|
|
struct Str {// expected-note+ {{candidate constructor}}
|
|
template <size_t N>
|
|
explicit(N > 7)
|
|
Str(char const (&str)[N]); // expected-note {{explicit constructor is not a candidate}}
|
|
};
|
|
|
|
template <size_t N>
|
|
Str::Str(char const(&str)[N]) { }
|
|
|
|
Str a = "short";
|
|
Str b = "not so short";// expected-error {{no viable conversion}}
|
|
|
|
}
|