[Bug c++/87464] New: Gcc reports hard error instead of SFINAE out the related method
alexejfink at gmx dot net
gcc-bugzilla@gcc.gnu.org
Fri Sep 28 12:38:00 GMT 2018
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87464
Bug ID: 87464
Summary: Gcc reports hard error instead of SFINAE out the
related method
Product: gcc
Version: 7.3.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: alexejfink at gmx dot net
Target Milestone: ---
Created attachment 44765
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=44765&action=edit
test code
The following code works with clang (7.x, 8.x) & VC (2015).
Trouble: GCC reports a hard error instead of SFINAE-drop the methods:
1. "tst.cpp:27:149: error: no type named ‘type’ in ‘struct
std::enable_if<false, int>’";
2. "tst.cpp:36:4: error: no type named ‘type’ in ‘struct std::enable_if<false,
SfinaeTest<int>&>’"
The clang and VC compilers do compile this places (besides the expected errors
in main())
//== sfinae_gcc_error.cpp =======================
#include <type_traits>
template<typename T>
class SfinaeTest
{
public:
SfinaeTest()
: dummy(nullptr)
{ }
SfinaeTest(const SfinaeTest& other)
: dummy(other.dummy)
{ }
SfinaeTest& operator =(const SfinaeTest& ot)
{
dummy= ot.dummy;
return *this;
}
public: // forbid non-const = const assignements
// gcc reports an error: "tst.cpp:27:149: error: no type named ‘type’ in
‘struct std::enable_if<false, int>’";
// Clang & VC do compile this constructor
template<typename TT, typename std::enable_if< std::is_same<T, const
TT>::value, int>::type = 0>
SfinaeTest(const SfinaeTest<TT>& other)
: dummy(other.dummy)
{ }
// gcc reports an error "tst.cpp:36:4: error: no type named ‘type’ in
‘struct std::enable_if<false, SfinaeTest<int>&>’"
// clang & VC do compile this method
template<typename TT>
typename std::enable_if< std::is_same<T, const TT>::value,
SfinaeTest&>::type
operator =(const SfinaeTest<TT>& ot)
{
dummy= ot.dummy;
return *this;
}
public:
T* dummy;
};
int main ()
{
typedef SfinaeTest<int> Ptr;
typedef SfinaeTest<const int> ConstPtr;
Ptr p;
ConstPtr c;
ConstPtr a_p( p); // good: non-const* -> const*
ConstPtr a_c( c); // good: const* -> const*
Ptr b_c( c); // expected error: const* -> non-const*; Extra
gcc-error: see L:25
ConstPtr c_p;
ConstPtr c_c;
Ptr d_p;
Ptr d_c;
c_p = p; // good: non-const* -> const*
c_c = c; // good: const* -> const*
d_p = p; // good: non-const* -> non-const*
d_c = c; // expected error: const* -> non-const*; Extra
gcc-error, see L:32
return 0;
}
//== GCC =======================
/tmp/sfinae_test$ /usr/bin/c++ --version
c++ (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
/tmp/sfinae_test$ /usr/bin/c++ -c sfinae_gcc_error.cpp
sfinae_gcc_error.cpp: In function ‘int main()’:
sfinae_gcc_error.cpp:58:20: error: no matching function for call to
‘SfinaeTest<int>::SfinaeTest(ConstPtr&)’
Ptr b_c( c); // expected error: const* -> non-const*; Extra
gcc-error: see L:25
^
sfinae_gcc_error.cpp:28:4: note: candidate: template<class TT, typename
std::enable_if<std::is_same<int, const TT>::value, int>::type <anonymous> >
SfinaeTest<T>::SfinaeTest(const SfinaeTest<TT>&)
SfinaeTest(const SfinaeTest<TT>& other)
^~~~~~~~~~
sfinae_gcc_error.cpp:28:4: note: template argument deduction/substitution
failed:
sfinae_gcc_error.cpp:27:98: error: no type named ‘type’ in ‘struct
std::enable_if<false, int>’
template<typename TT, typename std::enable_if< std::is_same<T, const
TT>::value, int>::type = 0>
^
sfinae_gcc_error.cpp:27:98: note: invalid template non-type parameter
sfinae_gcc_error.cpp:13:4: note: candidate: SfinaeTest<T>::SfinaeTest(const
SfinaeTest<T>&) [with T = int]
SfinaeTest(const SfinaeTest& other)
^~~~~~~~~~
sfinae_gcc_error.cpp:13:4: note: no known conversion for argument 1 from
‘ConstPtr {aka SfinaeTest<const int>}’ to ‘const SfinaeTest<int>&’
sfinae_gcc_error.cpp:9:4: note: candidate: SfinaeTest<T>::SfinaeTest() [with T
= int]
SfinaeTest()
^~~~~~~~~~
sfinae_gcc_error.cpp:9:4: note: candidate expects 0 arguments, 1 provided
sfinae_gcc_error.cpp:67:11: error: no match for ‘operator=’ (operand types are
‘Ptr {aka SfinaeTest<int>}’ and ‘ConstPtr {aka SfinaeTest<const int>}’)
d_c = c; // expected error: const* -> non-const*; Extra
gcc-error, see L:32
^
sfinae_gcc_error.cpp:17:16: note: candidate: SfinaeTest<T>&
SfinaeTest<T>::operator=(const SfinaeTest<T>&) [with T = int]
SfinaeTest& operator =(const SfinaeTest& ot)
^~~~~~~~
sfinae_gcc_error.cpp:17:16: note: no known conversion for argument 1 from
‘ConstPtr {aka SfinaeTest<const int>}’ to ‘const SfinaeTest<int>&’
sfinae_gcc_error.cpp:36:4: note: candidate: template<class TT> typename
std::enable_if<std::is_same<T, const TT>::value, SfinaeTest<T>&>::type
SfinaeTest<T>::operator=(const SfinaeTest<TT>&) [with TT = TT; T = int]
operator =(const SfinaeTest<TT>& ot)
^~~~~~~~
sfinae_gcc_error.cpp:36:4: note: template argument deduction/substitution
failed:
sfinae_gcc_error.cpp: In substitution of ‘template<class TT> typename
std::enable_if<std::is_same<int, const TT>::value, SfinaeTest<int>&>::type
SfinaeTest<int>::operator=<TT>(const SfinaeTest<TT>&) [with TT = const int]’:
sfinae_gcc_error.cpp:67:11: required from here
sfinae_gcc_error.cpp:36:4: error: no type named ‘type’ in ‘struct
std::enable_if<false, SfinaeTest<int>&>’
//== CLANG =======================
/tmp/sfinae_test$ /usr/bin/clang++ --version
clang version 6.0.0-1ubuntu2 (tags/RELEASE_600/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
/tmp/sfinae_test$ /usr/bin/clang++ -c sfinae_gcc_error.cpp
sfinae_gcc_error.cpp:58:14: error: no matching constructor for initialization
of 'Ptr' (aka 'SfinaeTest<int>')
Ptr b_c( c); // expected error: const* -> non-const*; Extra
gcc-error: see L:25
^ ~
sfinae_gcc_error.cpp:13:4: note: candidate constructor not viable: no known
conversion from 'SfinaeTest<const int>' to 'const SfinaeTest<int>' for
1st argument
SfinaeTest(const SfinaeTest& other)
^
sfinae_gcc_error.cpp:28:4: note: candidate template ignored: requirement
'std::is_same<int, const const int>::value' was not satisfied
[with TT = const int]
SfinaeTest(const SfinaeTest<TT>& other)
^
sfinae_gcc_error.cpp:9:4: note: candidate constructor not viable: requires 0
arguments, but 1 was provided
SfinaeTest()
^
sfinae_gcc_error.cpp:67:9: error: no viable overloaded '='
d_c = c; // expected error: const* -> non-const*; Extra
gcc-error, see L:32
~~~ ^ ~
sfinae_gcc_error.cpp:17:16: note: candidate function not viable: no known
conversion from 'SfinaeTest<const int>' to 'const SfinaeTest<int>' for
1st argument
SfinaeTest& operator =(const SfinaeTest& ot)
^
sfinae_gcc_error.cpp:36:4: note: candidate template ignored: requirement
'std::is_same<int, const const int>::value' was not satisfied
[with TT = const int]
operator =(const SfinaeTest<TT>& ot)
^
2 errors generated.
/tmp/sfinae_test$
//== END =======================
More information about the Gcc-bugs
mailing list