Fail to compile program using boost::spirit with Intel C++ compiler - c++

I'm trying to compile the following example http://www.boost.org/doc/libs/1_60_0/libs/spirit/example/qi/compiler_tutorial/calc3.cpp using Intel C++ compiler.
Compilation fails and I get 300 kB of errors. The first few are:
boost/fusion/container/vector/vector.hpp(69): error: namespace "boost::fusion::vector_detail::result_of" has no member "value_at_c"
: boost::is_convertible<Sequence, typename result_of::value_at_c<This, 0>::type>
^
boost/fusion/container/vector/vector.hpp(69): error: expected a ">"
: boost::is_convertible<Sequence, typename result_of::value_at_c<This, 0>::type>
^
boost/fusion/container/vector/vector.hpp(69): error: not a class or struct name
: boost::is_convertible<Sequence, typename result_of::value_at_c<This, 0>::type>
^
Command line is
icl.exe /I<path-to-boost> calc3.cpp
Boost version: 1.60, compiler version: 15.0.6.285 Build 20151119
Although I was able to fix the error by changing the line 69
struct is_convertible_to_first
: boost::is_convertible<Sequence, typename result_of::value_at_c<This, 0>::type>
{};
to
struct is_convertible_to_first
: boost::is_convertible<Sequence, typename boost::fusion::result_of::value_at_c<This, 0>::type>
{};
,
I'm still curious why is there a problem?

The most reasonable guess is that the result_of namespace that ICC finds within boost::fusion::vector_detail is only a workaround for non-conforming compilers (e.g. I think GCC 4.6 lacks some support there too) so, the name clash with boost::fusion::result_of only manifests there.
So it's a bug reportable with the library devs; the namespace should be qualified more to accomodate old compilers. (It's possible it won't be fixed anymore if said compilers aren't supported)

Related

Compile error in boost header file. Fails on Centos 7, compiles on Ubuntu 16.04

I am running into a strange compilation issue. Any help in resolving it would be greatly appreciated. I am linking my application against the boost libraries. I need to compile my app on both Centos and Ubuntu. Everything works fine on Ubuntu and the same code fails to compile on Centos 7. The location of the error is in boost. Not sure if the issue is actually in boost or if something else is causing the error to be show up in boost. I've come across this link when I searched the error. However, that issue was for an older version of boost. I've listed error output below:
/usr/local/include/boost/chrono/duration.hpp: In function 'constexpr typename boost::enable_if<boost::mpl::and_<boost::is_convertible<Rep1, typename boost::common_type<Rep1, Rep2>::type>, boost::is_convertible<Rep2, typename boost::common_type<Rep1, Rep2>::type> >, boost::chrono::duration<typename boost::common_type<Rep1, Rep2>::type, Period> >::type boost::chrono::operator*(const boost::chrono::duration<Rep, Period>&, const Rep2&)':
In file included from /usr/local/include/boost/chrono/time_point.hpp:33:0,
from /usr/local/include/boost/thread/lock_types.hpp:22,
from /usr/local/include/boost/thread/lock_algorithms.hpp:11,
from /usr/local/include/boost/thread/locks.hpp:10,
...
/usr/local/include/boost/chrono/duration.hpp:575:34: error: type/value mismatch at argument 1 in template parameter list for 'template<class Rep, class Period> class boost::chrono::duration'
typedef duration<CR, Period> CD;
^
/usr/local/include/boost/chrono/duration.hpp:575:34: error: expected a type, got '13u'
/usr/local/include/boost/chrono/duration.hpp:575:38: error: invalid type in declaration before ';' token
typedef duration<CR, Period> CD;
Corresponding code from /usr/local/include/boost/chrono/duration.hpp:
// Duration *
template <class Rep1, class Period, class Rep2>
inline BOOST_CONSTEXPR
typename boost::enable_if <
mpl::and_ <
boost::is_convertible<Rep1, typename common_type<Rep1, Rep2>::type>,
boost::is_convertible<Rep2, typename common_type<Rep1, Rep2>::type>
>,
duration<typename common_type<Rep1, Rep2>::type, Period>
>::type
operator*(const duration<Rep1, Period>& d, const Rep2& s)
{
typedef typename common_type<Rep1, Rep2>::type CR;
typedef duration<CR, Period> CD;
return CD(CD(d).count()*static_cast<CR>(s));
}
I get this error on Centos7. Does not happen on Ubuntu.
Centos Version:
Boost: 1.58.0, OS: Centos 7, C++: g++ 4.8.5
Ubuntu Versions:
Boost: 1.58.0, OS: Ubuntu 16.04, C++: g++ 5.4.0
Not sure if the C++ compiler difference is the issue. The default version of c++ compiler on Centos7 is 4.8.5. BTW, the default boost version on CentOS7 is 1.53.2. I compiled and installed boost 1.58.0 version to minimize the variables. Any help is greatly appreciated. Thanks.
My guess (and that's all it is, a guess) based on the error message is that somewhere you've got:
#define CR 13u
and that's causing the compilation error.

MSVC pointer type attributes

I recently ran into a compilation warning (promoted to error) using the 64-bit VS2013 compiler (update 3) making me aware of the existence of pointer type attributes.
The warning indicated a loss of precision as I was about to assign something of type 'Object *' to 'Object * __ptr32'.
I didn't hear about this '__ptr32' suffix yet, so I did some googling and found the following link: http://blog.aaronballman.com/2013/05/msvc-pointer-type-attributes/ .
After reading this, it became clear that I shouldn't simply ignore this warning as I might get ugly bugs in my 64-bit application...
Trying to pinpoint the problem further, I wrote following small program:
#include <type_traits>
struct O { };
struct OD { using V = O *; };
template <typename X, typename Y> struct expect_equal { static_assert(std::is_same<X, Y>::value, "Types do not correspond."); };
template <class D> using VD = typename D::V;
template <class D> struct Exp { template <template <class> class T> using DT = T<D>; };
int main(void)
{
expect_equal<Exp<OD>::DT<VD>, O *> e;
return 0;
}
While it would compile using clang, I got the following error/assertion failure using my MSVC 64-bit compiler (note: the 32-bit compiler did not yield compilation errors):
Microsoft (R) C/C++ Optimizing Compiler Version 18.00.30723 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
test.cpp
test.cpp(6) : error C2338: Types do not correspond.
test.cpp(13) : see reference to class template instantiation 'expect_equal<O * __ptr32,O *>' being compiled
I was wondering whether someone could indicate what I am doing wrong here: I don't use an explicit pointer type attribute anywhere. This also might be a an unspecified behavior or a bug of either the STL implementation or the compiler, but most likely I am missing some important point here... Thanks in advance!

Error with type alias

I would like to use a type alias to create a template with one argument, from a template with two arguments:
// forward declaration
template<int Id, typename MixtureManager> class MixtureBridge;
/**
* Specialization of the MixtureTraits for the Gaussian_sjk_ model
**/
template<>
struct BridgeTraits<STK::Clust::Gaussian_sjk_>
{
// ... some traits
};
template <typename MixtureManager>
using GaussianBridge_sjk_m = MixtureBridge<STK::Clust::Gaussian_sjk_, MixtureManager>;
I get the following error message:
mixt_GaussianBridges.h:65:1: error: expected unqualified-id before 'using'
What is wrong with my syntax ?
Note: I am working with gcc 4.6.3, on Windows
Template aliases are not supported in gcc 4.6 : https://gcc.gnu.org/gcc-4.6/cxx0x_status.html
upgrade your compiler to a more recent version.
Alias-declarations are only supported from gcc 4.7 onwards
https://gcc.gnu.org/gcc-4.7/changes.html

Using clang 3.1 with initializer lists

When I compile this code:
template<typename T>
struct S {
std::vector<T> v;
S(initializer_list<T> l) : v(l) {
std::cout << "constructed with a " << l.size() << "-element list\n";
}
};
using the following command line:
clang++ -std=c++11 -stdlib=libc++ initializer_list.cpp
I get the following error.
initializer_list.cpp:12:23: error: expected ')'
S(initializer_list<T> l) : v(l) {
Does anyone know the fix if any??
Thanks in advance
You probably meant to write std::initializer_list<T>. Make sure you include <initializer_list>.
Your code sample is incomplete. It would be useful if you can provide a complete example. The problem with the code as written is that you're missing
#include <initializer_list>
#include <vector>
#include <iostream>
... and initializer_list is in namespace std, so you're also missing a std:: from your constructor declaration.
However, since you've claimed that neither of these is the issue, the most likely cause would seem to be that your C++ standard library implementation doesn't provide std::initializer_list. That would be the case if Clang is using GCC's libstdc++, and you do not have a suitably new version of that installed: you need at least version 4.4, but note that a patch is required to fix bugs in libstdc++-4.4 in order to make it work with Clang in C++11 mode, otherwise you will get errors about type_info and various other problems.
Also, you say that the diagnostic you received is this:
initializer_list.cpp:12:23: error: expected ')'
S(initializer_list<T> l) : v(l) {
^
(I've reconstructed the caret from the provided column number; it would be useful to preserve it in future questions.) For any of the above explanations, this will not be the first diagnostic which Clang produces; that would be something along the lines of:
initializer_list.cpp:12:5: error: no template named 'initializer_list'; did you mean 'std::initializer_list'?
S(initializer_list<T> l) : v(l) {
^~~~~~~~~~~~~~~~
std::initializer_list
So either you've missed out the first diagnostic from your question, or the problem is that you have declared some other (non-template) type named initializer_list in the code you omitted in your question, and that is hiding std::initializer_list. Without seeing the rest of your code or the rest of your diagnostics, it's not possible to tell which.

error: cannot convert ‘int (^)(int)’ to ‘R (^)(T)’ in initialization

I am trying to understand how to best make use of blocks in my templated class.
I have the following code snippet:
template<typename T, typename R>
class MyClass {
public:
typedef R (^Block)(T);
MyClass(Block blk) {}
};
void testMyClass() {
MyClass<int,int>::Block blk(^(int arg) {
return 1 + arg;
});
}
When I try to compile this, I get the following error message:
error: cannot convert ‘int (^)(int)’ to ‘R (^)(T)’ in initialization
Am I missing something obvious? Am I trying to do something that is not allowed? GCC accepts the program if I do the same thing without templates.
This is an issue in GCC. I tested your program under LLVM 3 and it compiled just fine.
There are a number of problems in GCC 4.2's implementation of blocks, sometimes they can be worked around by fully qualifying your block declarations ^int(int arg){return 1 + arg;} but in this case it was unable to work around this issue. I would highly recommend moving to use LLVM/Clang for any further work with Obj-C Blocks. Its C++ support is very good these days, especially for C++03 support.