I am trying to setup my machine to be able to compile c++20 code. I have a simple example code
#include <concepts>
#include <iostream>
template<typename T>
requires std::integral<T>
auto gcd(T a, T b) {
if(b == 0) return a;
else return gcd(b, a%b);
}
int main() {
std::cout << "\n";
std::cout << gcd(100,10) << "\n";
}
which I am trying to compile on a MacOS (11.5.1/BigSur).
xcode version - Xcode 12.5.1
Build version 12E507
clang version - Apple clang version 12.0.5 (clang-1205.0.22.11)
compilation command
g++ -std=c++20 myfile.cpp
I get the following error:
myfile.cpp:25:24: error: 'T' does not refer to a value
requires std::integral<T>
^
myfile.cpp:24:19: note: declared here
template<typename T>
^
myfile.cpp:25:15: error: no member named 'integral' in namespace 'std'; did you mean 'internal'?
requires std::integral<T>
~~~~~^~~~~~~~
internal
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++/v1/ios:960:1: note: 'internal' declared here
internal(ios_base& __str)
^
myfile.cpp:26:1: error: expected expression
auto gcd(T a, T b) {
^
3 errors generated
Need help with this.
Consider the following program:
struct S {
enum E {
e
};
template<E> void f() = delete;
};
template<> void S::f<S::E::e>() {}
int main() {
S s;
s.f<S::E::e>();
}
GCC 5.4.0 compiles the code, while clang 3.8.0 fails:
$ clang++ -std=c++14 main.cpp
main.cpp:10:20: error: redefinition of 'f'
template<> void S::f<S::E::e>() {
^
main.cpp:8:20: note: previous definition is here
template<> void S::f<S::E::e>();
^
main.cpp:14:11: error: no matching member function for call to 'f'
s.f<S::E::e>();
~~^~~~~~~~~~
main.cpp:5:22: note: candidate template ignored: substitution failure [with $0 = S::E::e]
template<E> void f() = delete;
^
2 errors generated.
Is clang correct and GCC wrong or is it the opposite? Note that if the delete specifier is removed, then clang compiles the code.
this seems defect report Explicit specialization of deleted function template , as you can see from here the issue seems fixed in clang since 3.9.0.
This question already has an answer here:
Specialized template function with deleted "general" case fails to compile with g++ <=4.8.0 and clang++
(1 answer)
Closed 5 years ago.
I am having trouble with a template specialisation of a deleted template function. The code below shows the problem boiled down to a MWE:
#include <iostream>
#include <string>
template<typename T>
inline std::string typeToString() = delete;
template<>
inline std::string typeToString<float>()
{
return "float";
}
int main()
{
std::cout << typeToString<float>() << std::endl;
}
With gcc 7 this compiles fine. However, with Apple LLVM 8.0.0 I get the following error messages:
clang test.cpp -std=c++1z
test.cpp:8:28: error: inline declaration of 'typeToString<float>' follows non-inline definition
inline std::string typeToString<float>()
^
test.cpp:8:28: note: previous definition is here
test.cpp:15:18: error: call to deleted function 'typeToString'
std::cout << typeToString<float>() << std::endl;
^~~~~~~~~~~~~~~~~~~
test.cpp:8:28: note: candidate function [with T = float] has been explicitly deleted
inline std::string typeToString<float>()
This looks to be a bug. If you compile with clang 3.9.1 or above it will compile. The following examples on Golbolt and Wandbox with clang 3.8.1 fail but when we change to 3.9.1 they both compile.
2 problem:
#include <iostream>
#include <string>
#include <regex>
int main() {
std::u32string lines[] = {U"Roses are #ff0000",
U"violets are #0000ff",
U"all of my base are belong to you"};
std::basic_regex<char32_t> color_regex(U"#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})");
/*
for (const auto &line : lines) {
std::cout << line << ": "
<< std::regex_search(line, color_regex) << '\n';
}
std::smatch color_match;
for (const auto &line : lines) {
std::regex_search(line, color_match, color_regex);
std::cout << "matches for '" << line << "'\n";
for (size_t i = 0; i < color_match.size(); ++i) {
std::ssub_match sub_match = color_match[i];
std::string sub_match_str = sub_match.str();
std::cout << i << ": " << sub_match_str << '\n';
}
}
*/
return 0;
}
compile with gcc : it work:
g++ -g -O0 -std=c++11 regexp.cpp -o executable
compile with clang: it not work at all:
clang++ -g -O0 -std=c++11 regexp.cpp -o executable
execute with gcc generated file:
terminate called after throwing an instance of 'std::bad_cast'
what(): std::bad_cast
Abandon (core dumped)
error in clang compilation:
In file included from regexp.cpp:3:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/regex:60:
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/regex_compiler.h:413:20: error: non-type template argument is not a constant expression
std::bitset<1 << (8 * sizeof(_CharT))>,
^~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/regex_compiler.tcc:398:53: note: in instantiation of template class 'std::__detail::_BracketMatcher<std::regex_traits<char32_t>, false, false>' requested here
_BracketMatcher<_TraitsT, __icase, __collate> __matcher
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/regex_compiler.tcc:316:25: note: in instantiation of function template specialization 'std::__detail::_Compiler<std::regex_traits<char32_t>
>::_M_insert_character_class_matcher<false, false>' requested here
__INSERT_REGEX_MATCHER(_M_insert_character_class_matcher);
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/regex_compiler.tcc:288:8: note: expanded from macro '__INSERT_REGEX_MATCHER'
__func<false, false>(args);\
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/regex_compiler.tcc:136:17: note: in instantiation of member function 'std::__detail::_Compiler<std::regex_traits<char32_t> >::_M_atom' requested here
if (this->_M_atom())
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/regex_compiler.tcc:118:17: note: in instantiation of member function 'std::__detail::_Compiler<std::regex_traits<char32_t> >::_M_term' requested here
if (this->_M_term())
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/regex_compiler.tcc:97:13: note: in instantiation of member function 'std::__detail::_Compiler<std::regex_traits<char32_t> >::_M_alternative' requested here
this->_M_alternative();
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/regex_compiler.tcc:82:13: note: in instantiation of member function 'std::__detail::_Compiler<std::regex_traits<char32_t> >::_M_disjunction' requested here
this->_M_disjunction();
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/regex_compiler.h:155:14: note: in instantiation of member function 'std::__detail::_Compiler<std::regex_traits<char32_t> >::_Compiler' requested here
return _Cmplr(__first, __last, __traits, __flags)._M_get_nfa();
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/regex.h:524:27: note: in instantiation of function template specialization 'std::__detail::__compile_nfa<std::regex_traits<char32_t> >' requested here
_M_automaton(__detail::__compile_nfa(_M_original_str.c_str(),
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/regex.h:452:9: note: in instantiation of function template specialization 'std::basic_regex<char32_t, std::regex_traits<char32_t> >::basic_regex<const
char32_t *>' requested here
: basic_regex(__p, __p + _Rx_traits::length(__p), __f)
^
regexp.cpp:10:29: note: in instantiation of member function 'std::basic_regex<char32_t, std::regex_traits<char32_t> >::basic_regex' requested here
std::basic_regex<char32_t> color_regex(U"#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})");
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/regex_compiler.h:413:22: note: shift count 32 >= width of type 'int' (32 bits)
std::bitset<1 << (8 * sizeof(_CharT))>,
^
...
...
...
...
Have someone already try it?
$ clang --version
Ubuntu clang version 3.4-1ubuntu3 (tags/RELEASE_34/final) (based on LLVM 3.4)
Target: x86_64-pc-linux-gnu
Thread model: posix
$ g++ --version
g++ (Ubuntu 4.9.1-3ubuntu2~14.04.1) 4.9.1
According to this reference
Two specializations of std::regex_traits are defined by the standard library:
std::regex_traits<char>
std::regex_traits<wchar_t>
These specializations make it possible to use std::basic_regex<char> (aka std::regex) and std::basic_regex<wchar_t> (aka std::wregex), but in order to use, for example, std::basic_regex<char32_t>, user-provided specializtion std::regex_traits<char32_t> needs to be defined.
std::regex_traits<char32_t> is not provided by the standard. You must implement it yourself in order to use std::basic_regex<char32_t>.
The following code doesn't work with clang 3.3. but it does word with g++ 4.8.1. Boost version is 1.55.
#include <boost/concept_check.hpp>
template <typename X>
class ConceptsBase {};
int main() {
auto l = [](){};
BOOST_CONCEPT_ASSERT((ConceptsBase<decltype(l)>));
return 0;
}
g++ -std=c++0x test.cpp -I /home/wygos/libs/boost_1_55_0/include/ # works fine!
clang++ -std=c++0x test.cpp -I /home/wygos/libs/boost_1_55_0/include/
gives:
test.cpp:9:5: error: non-type template argument refers to function 'failed' that does not have linkage
BOOST_CONCEPT_ASSERT((ConceptsBase<decltype(l)>));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/wygos/libs/boost_1_55_0/include/boost/concept/assert.hpp:44:5: note: expanded from macro 'BOOST_CONCEPT_ASSERT'
BOOST_CONCEPT_ASSERT_FN(void(*)ModelInParens)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/wygos/libs/boost_1_55_0/include/boost/concept/detail/general.hpp:70:6: note: expanded from macro 'BOOST_CONCEPT_ASSERT_FN'
&::boost::concepts::requirement_<ModelFnPtr>::failed> \
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/wygos/libs/boost_1_55_0/include/boost/concept/detail/general.hpp:38:17: note: non-type template argument refers to function here
static void failed() { ((Model*)0)->~Model(); }
My lucky guess is that it might be connected to:
http://llvm.org/bugs/show_bug.cgi?id=17030