Try out standard library <concepts> with GCC - c++

GCC supports the -fconcepts switch, providing experimental core language concept features.
Is there also a way to use (an experimental version of) the standard library implementation?
It would be great to have std::derived_from, std::convertible_to, std::destructible and friends available when designing concepts.
#include <concepts>
template<typename T>
concept Fooable = requires(T f) {
{ bar(f) } -> std::convertible_to<float>;
};

The question does not clarify the version of GCC. Actually starting from GCC 10 the concepts are supported with -std=c++20 command-line option both by the compiler and standard library implementation (libstdc++) coming with it. Demo: https://gcc.godbolt.org/z/9G5Y1KEeT

Related

XCode does not see new C++17 feature

I try to increase C++ version in XCode MacOS BigSure(11.0.4).
And optional header is found good but when I try to use std::optional I get an error No template named optional in std. In optional header I find implementation but part with
namespace std {
template <class T> optional;
...
}
is under the /**/.
I increase version in settings to C++17 and standard library to libc++(LLVM with C++11 support). clang version is 12.0.5.
How can i fix this trouble?

Is std::transform_reduce without execution policy portable?

I can compile the following code (using std::transform_reduce) with gcc 9.2.1 on both Fedora and Ubuntu, but attempting to compile on clang see godbolt fails, and I've got a report that some FSF version of gcc 9.2.1 also refuses to compile the code, requiring a std::execution_policy as the first argument to the std::transform_reduce.
#include <vector>
#include <algorithm>
#include <numeric>
auto brokenvector(std::vector<int> const& a, std::vector<int> const& b)
{
return std::transform_reduce(cbegin(a), cend(a), cbegin(b), 0, std::plus<>{},std::multiplies<>{});
}
I specifically cannot use a std::execution_policy here, and both cppreference and the C++ draft standard document n4659 show overloads without an execution policy.
Have I stepped into some kind of political minefield where half of the available compilers refuse to implement the standard, or is the code incorrect?
This is a libstdc++ vs libc++ issue. libc++ implements the function and you can see it working with clang on godbolt using -stdlib=libc++ in this live example. gcc implements it now in trunk, but the currently released versions do not. The function was added in this commit.

How to work with regular expressions in c++ with gcc 4.8 and without C++11 flag?

I recently found out that regex support in gcc 4.8 is incomplete, and it was truly implemented in gcc 4.9 (see Is gcc 4.8 or earlier buggy about regular expressions?).
So, wanting to work with regex in my c++ program, I updated my gcc to 4.9 following this instructions (https://askubuntu.com/questions/466651/how-do-i-use-the-latest-gcc-4-9-on-ubuntu-14-04).
Now when I try to compile my program it says that in order to #include <regex> I have to specify the compiler flag -std=c++11, which I did, and now I'm faced with new compilation problems that I didn' had before (‘constexpr’ needed for in-class initialization of static data member).
Given that, I think for now it is best to stick to gcc 4.8 and not specify the gnu++11 flag in compilation. Back to square 1.
So, can I work with regular expressions in c++ if I do not want to switch to gcc 4.9 nor flag the compiler with c++11? Is there another way?
Thanks!
PS: actually it's the c++11 flag that causes the compilation issues, not the version of gcc, right?
You can install the PCRE library and use that instead of the C++11 standard regular expressions. PCRE is really designed as a C library/interface, rather than C++, but writing a couple of trivial wrapper classes or just using it as a C library is quite easy.
The error most likely means you were relying on a non-standard GCC extension to initialize a non-integer type like this:
struct X {
static const double d = 3.14;
};
That was not valid in C++98, but was supported by GCC.
The C++11 standard added support for initializing non-integer types like that, but you need to use constexpr e.g.
struct X {
static constexpr double d = 3.14;
};
When you compile with -std=c++11 or -std=gnu++11 the old GCC-specific extension is no longer supported. and you have to use the standard C++11 way, using constexpr.
So you could easily resolve the error by changing it to constexpr, or to make it compatible with GCC's C++98 extension and also C++11:
struct X {
#if __cplusplus > 199711L
static constexpr double d = 3.14;
#else
// this is non-standard but allowed by GCC in C++98 mode
static const double d = 3.14;
#endif
};
That will allow you to compile with -std=c++11, and so you can use GCC 4.9's working std::regex.

How to detect the libstdc++ version in Clang?

I would like to write a "portable" C++ library in Clang. "Portable" means that I detect (in C preprocessor) what C++ features are available in the compilation environment and use these features or provide my workarounds. This is similar to what Boost libraries are doing.
However, the presence of some features depends not on the language, but on the Standard Library implementation. In particular I am interested in:
type traits (which of them are available and with what spelling)
if initializer_list being constexpr.
I find this problematic because Clang by default does not use its own Standard Library implementation: it uses libstdc++. While Clang has predefined preprocessor macros __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__, they are hardcoded to values 4, 2, 1 respectively, and they tell me little about the available libstdc++ features.
How can I check in Clang preprocessor what version of libstdc++ it is using?
Clang does come with its own standard library implementation, it's called libc++. You can use it by adding -stdlib=libc++ to your compile command.
That being said, there are various ways to check Clang/libstdc++ C++ support:
Clang has the __has_feature macro (and friends) that can be used to detect language features and language extenstions.
Libstdc++ has its own version macros, see the documentation. You'll need to include a libstdc++ header to get these defined though.
GCC has its version macros which you already discovered, but those would need to be manually compared to the documentation.
And also, this took me 2 minutes of googling.
This is what I think would help. It prints the value of the _LIBCPP_VERSION macro:
#include <iostream>
#include <string>
using namespace std;
int main(int argc, const char * argv[])
{
cout<<"Value = "<<_LIBCPP_VERSION<<endl;
return 0;
}
Compile it again the version of clang you want the info for.

No type named 'atomic' in namespace 'std'

Why doesn't
std::atomic<int> index;
Work?
Currently using LLVM 3.1 with these params
C Language Dialect GNU [-std=gnu99]
C++ Language Dialect [-std=c++11]
C++ Standard Library libc++(LLVM C++ standard library with C++11 support)
There are several things that need to be true for your code to work:
You need to #include <atomic>
You need to compile the code as C++11 or C++14 (-std=c++11 or -std=c++14 (or c++0x for older compilers))
Your compiler and standard library needs to support enough of C++11 to provide atomic (http://clang.llvm.org/cxx_status.html)
Adding -std=c++11 to CXXFLAGS in my Makefile -> that works for me!
You need to write it as the following to defined variable.
std::atomic<std::int> index;