I'm having trouble working with lambda functions in the Intel compiler, in particular, the following code won't compile:
template<typename T>
std::function<T (int)> make_func(T x) {
return [=](int index) -> T
{
return x;
};
}
The error I get is
error: namespace "std" has no member "function"
The code compiles and runs fine on my Mac, (macports gcc version 4.5). The error is at work, where we use the Intel compiler version 11.1. It does accept lambda functions (with the -std=c++0x option), such as:
auto lam = [=](int j) -> int {
printf("testing for lambdas: %d\t%d\n", n, j);
return n;
};
int g = lam(7);
The version of gcc installed at work is 4.1.2, so I'm guessing that the standard library is old?
/bin/libc.so.6
says it's version 2.5 compiled with gcc 4.1.2.
Is there a way around this?
thanks in advance for any help
I get the same behavior with icc 11.1 on a system where gcc 4.5.2 is installed.
g++'s header <functional> is protected with #ifdef __GXX_EXPERIMENTAL_CXX0X__ which is not defined when icc is used.
I would consider switching to boost::function in this setup, which of course works with icc.
Well, the code shown doesn't include a single header. And yet you refer to the standard library std::function.
So no, it doesn't compile. As with any other part of the standard library, you need to include the header where std::function is defined: <functional>.
Related
I happen to find that GCC and Clang differ in the compilation of the following code:
struct Foo
{
int mem = 42;
};
int main()
{
constexpr Foo foo;
static_assert(__builtin_constant_p(foo));
return 0;
}
I compile with g++ -std=c++17 and clang++ -std=c++17.
In particular,
g++ g++-9 (Homebrew GCC 9.3.0_1) 9.3.0 compiles, whereas
clang++ Apple clang version 11.0.3 (clang-1103.0.32.62) fails to compile, complaining that
error: static_assert failed due to requirement '__builtin_constant_p(foo)'
static_assert(__builtin_constant_p(foo));
^ ~~~~~~~~~~~~~~~~~~~~~~~~~
I didn't find any hint that there should be any difference regarding __builtin_constant_p.
For __builtin_constant_p
GCC says
You can use the built-in function __builtin_constant_p to determine if a value is known to be constant at compile time ...
Clang
says
Clang supports a number of builtin library functions with the same syntax as GCC, including things like __builtin_nan, __builtin_constant_p, __builtin_choose_expr, __builtin_types_compatible_p, __builtin_assume_aligned, __sync_fetch_and_add, etc.
Question: While I know __builtin_constant_p is a compiler extension, which one should be the correct one?
Both are poorly documented so I doubt there is a proper answer to your question.
If you need a workaround: it seems that clang gives up if the argument is not an int.
So this works:
struct Foo
{
int mem = 42;
};
int main()
{
constexpr Foo foo;
static_assert(__builtin_constant_p(foo.mem));
return 0;
}
I am trying to port some C++17 code I made on ubuntu (gnu++11)
typedef boost::variant<int, float, std::string > Variant;
using Func = std::function<std::vector<unsigned char>(std::vector<Variant>)>;
void addexecutorfunc( Func callback, const auto&...args )
{
std::vector<Variant> vec = {args...};
executor.add(vec, std::move(callback));
}
this code compiles and works fine on ubuntu, but when trying to compile on windows with visual studio 2017(v141) [ISO C++ Latest Draft Standard(/std:c++latest)], then I get following:
error C3533: a parameter cannot have a type that contains 'auto'
I think perhaps it has to do with the Concepts lite not being implemented in current C++17 version or is this wrong?
If I could setup compiler to use auto as parameter and parameter packs, then that would be best, but if this is not possible, then I will have to rewrite my code to follow C++17 windows standard - any suggestions on how to do this without ending up in a template hell
void addexecutorfunc( Func callback, const auto&...args )
auto as a parameter to a (non-lambda) function is a GNU extension. It is not part of standard C++17, and is not supported by either of the other two major C++ compilers, Clang and MSVC. Rather unfortunately, GCC seems to allow it in -std=c++14 mode as well as with -std=gnu++14.
The standard C++ equivalent would be a function template
template <typename... Ts>
void addexecutorfunc(Func callback, const Ts&... args)
which should work as expected.
The code below sorting in Visual Studio successfully.
But, in Ubuntu GCC 4.4.7 compiler throws error. It seems it's not familiar with this type of syntax.
How shall I fix this line to make code working in GCC? (the compiler is remote. So I can't upgrade the GCC version either).
What I'm doing right here is:sorting Vector B elements regarding their fitness values
//B is a Vector of class Bird
//fitness is a double - member of Bird objects
vector<Bird> Clone = B;
sort(Clone.begin(), Clone.end(), [](Bird a, Bird b) { return a.fitness> b.fitness; });
//error: expected primary expresssion before '[' token
//error: expected primary expresssion before ']' token...
(Note: this 3 piece of lines compiling successful in MSVC but not in GCC)
my answer is
bool X_less(Bird a, Bird b) { return a.fitness > b.fitness; }
std::sort(Clone.begin(), Clone.end(), &X_less);
It seems to work. Is it a function or not? I don't know its technical name, but it seems to work. I am not much familiar with C++.
You will need to upgrade your C++ as 4.4 is too old to support Lambda. I have Gcc 4.8, but it still requires you enable c++11 that includes lambda functions, so
$ g++ -std=c++11 x.cc
compiles this fine
#include <algorithm>
#include <functional>
#include <vector>
using namespace std;
int main()
{
vector<int> Clone;
sort(Clone.begin(), Clone.end(), [](int a, int b) { return a> b; });
}
but still gives errors without -std=c++11 option
How can I declare a function in a class that uses return type deduction?
This is fine:
auto foo() {
return 5;
}
But this does not work:
class Test {
auto foo();
};
auto Test::foo() {
return 5;
}
internal compiler error: in gen_type_die_with_usage, at dwarf2out.c:19486
I don't know if it has anything to do with it but I am using QtCreator 3.3.
EDIT:
I am using Qt 5.4 and QtCreator 3.3.
I have added CONFIG += c++14 to the project file.
By default, I am using GCC 4.8.2 and I guess this is why I get the error (I need 4.9). However when I use Clang 3.5 (3.4 is needed) it says
error: 'auto' return without trailing return type; deduced return types are a C++1y extension
EDIT2: This seems to be a bug with Qt and not with GCC. Outside of Qt I can write class functions with return type deductions and it compiles and runs just fine with GCC 4.8.2 and Clang 3.5.0
Boost Intrusive's unordered_set is broken if you do a vanilla install of Fedora 17 which comes with GCC 4.7 and Boost 1.48, and use C++11 mode. On Fedora 16, which comes with GCC 4.6.2 and Boost 1.47, it works. This breaks real code, and it even breaks the example in the official documentation:
#include <boost/intrusive/unordered_set.hpp>
using namespace boost::intrusive;
struct MyClass : public unordered_set_base_hook<>
{};
typedef unordered_set<MyClass>::bucket_type bucket_type;
typedef unordered_set<MyClass>::bucket_traits bucket_traits2;
int main()
{
bucket_type buckets[100];
unordered_set<MyClass> uset(bucket_traits2(buckets, 100)); // FAILS
}
The error message:
/usr/include/boost/intrusive/hashtable.hpp:227:65: error: use of deleted function ‘constexpr boost::intrusive::detail::bucket_traits_impl >::type>::bucket_traits_impl(const boost::intrusive::detail::bucket_traits_impl >::type>&)’
In file included from /usr/include/boost/intrusive/hashtable.hpp:30:0,
from /usr/include/boost/intrusive/unordered_set.hpp:18,
from t.cpp:23:
/usr/include/boost/intrusive/detail/hashtable_node.hpp:80:8: note: ‘constexpr boost::intrusive::detail::bucket_traits_impl >::type>::bucket_traits_impl(const boost::intrusive::detail::bucket_traits_impl >::type>&)’ is implicitly declared as deleted because ‘boost::intrusive::detail::bucket_traits_impl >::type>’ declares a move constructor or move assignment operator
Here is the code it refers to, hashtable.hpp:227:
template<class BucketTraits>
bucket_plus_size(BOOST_FWD_REF(BucketTraits) b_traits)
: bucket_traits_(::boost::forward<BucketTraits>(b_traits))
{}
In Boost 1.47, this was:
bucket_plus_size(const bucket_traits &b_traits)
: bucket_traits_(b_traits)
{}
BOOST_FWD_REF(TYPE) on my system is defined as TYPE && by default, but if BOOST_NO_RVALUE_REFERENCES is defined then it becomes const TYPE &. And if I do define it that way, the code compiles!
Any thoughts on why this is? Is it GCC's fault, Boost's, Fedora's, or mine?
This looks like the same problem described at http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53234
i.e. Boost 1.48 assumes the old behaviour of GCC 4.6, but GCC 4.7 was changed to implement the correct C++11 semantics regarding implicitly-defined copy/move constructors.