I'm using MoSync IDE to build my C++ code for mobile platform. Initially the C++ code was built separately by Visual Studio 2010 without any problems. But when I used MoSync IDE to rebuild the C++ code, it generated some error message. My C++ code uses STL library like std::pair and std::vector classes. Below is the code that was compiled as error in MoSync IDE. MoSync uses GCC 3.4.6. So I assume this is caused by the GCC compiler.
template<typename T>
vector< pair<T, int> > histogram(const vector<T>& x, int numBins)
{
T maxVal, minVal, range, delta, leftEdge, rightEdge;
int i, dummyIdx;
vector<T>::iterator pt;
vector< pair<T, int> > counts(numBins, make_pair(T(), 0));
vector<T> y(x);
//other code ...
}
The error message is:
error: expected `;' before "pt" (line 6)
This template function calculates histogram given the input vector x and numBins, and it returns "counts" as the pair of (bins, counts). Originally I compiled this C++ code in Visual Studio 2010 without any errors. But GCC in MoSync IDE gave me this error message. So this baffles me a lot why this fails to build in GCC.
vector<T>::iterator is dependent type so you need to use typename:
typename vector<T>::iterator pt;
See Where and why do I have to put the "template" and "typename" keywords?
Related
I'm currently trying to deduce a std::tuple type from several std::vectors that are passed as parameters. My code works fine using gcc, but the compilation fails with Visual Studio Professional 2019 with the message "fatal error C1202: recursive type or function dependency context too complex".
It has been mentioned for my previous post (C++ "fatal error C1202: recursive type or function dependency context too complex" in visual studio, but gcc compiles) that the problem is caused by template recursion as explained in C++ template compilation error - recursive type or function dependency. However, I don't see where the recursion occurs.
So my questions are:
Why is there an (infinite) recursion?
How can it be resolved?
Here is the code (I'm bound to C++11):
#include <tuple>
#include <vector>
template <typename TT,typename Add>
auto addTupBase(TT t,std::vector<Add> a) ->decltype (std::tuple_cat(t,std::make_tuple(a[0])))
{
return std::tuple_cat(t,std::make_tuple(a[0])) ;
}
template <typename TT,typename Add,typename... Args>
auto addTupBase(TT t,std::vector<Add> a,Args... args)-> decltype(addTupBase(addTupBase(t,a),args...))
{
return addTupBase(addTupBase(t,a),args...);
}
template <typename T,typename... Args>
auto addTup(std::vector<T> in,Args... args) ->decltype(addTupBase(std::make_tuple(in[0]),args...))
{
return addTupBase(std::make_tuple(in[0]),args...);
}
int main()
{
using TupleType = decltype(addTup(std::vector<char>{2},std::vector<int>{5},std::vector<double>{32423}));
TupleType t;
std::get<2>(t) = 342.2;
return 0;
}
MSVC has some conformance issues when running in /permissive mode and "The Microsoft C++ compiler doesn't currently support binding nondependent names when initially parsing a template. This doesn't conform to section 14.6.3 of the C++ 11 ISO specification. This can cause overloads declared after the template (but before the template is instantiated) to be seen.".
If you instead use /permissive- "The compiler [...] implements more of the requirements for two-phase name look-up" and will compile your program as-is.
Also note that you aren't actually using C++11. MSVC 19.24 supports C++14 and up.
I just came across a weird problem that happens ONLY on MSVC with Clion but not on other compilers(I tried gcc on Linux and Visual Studio both no such problem, with the same code).
With these codes:
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int>v = {1,2,3,4,5};
make_heap(v.begin(), v.end());
v.push_back(6);
push_heap(v.begin(), v.end());
}
an error "In instantiation of function template specialization 'std::push_heapstd::_Vector_iterator<std::_Vector_val<std::_Simple_types<int > > >' no type named 'value_type' in 'std::indirectly_readable_traitsstd::_Vector_iterator<std::_Vector_val<std::_Simple_types<int > > >'" will then be shown
is it a bug of Clion or MSVC?
P.S.
I can still build and run it so it might not be a compiler error; (Making me even more confused)
It looks like you cannot intialize vector with the following command:
vector<int>v = {1,2,3,4,5};
Change it to:
vector<int> vect{ 1, 2, 3, 4, 5 };
Compile and run the code and see if it still has problems.
EDIT:
Some people are saying it is unlikely however look at the link:
What is the easiest way to initialize a std::vector with hardcoded elements?
If you scroll down to the second answer it says:
If your compiler supports C++11, you can simply do:
std::vector<int> v = {1, 2, 3, 4};
As you did not tell us your compiler version and environment it is very hard to determine if this is the problem. Also note that:
This is available in GCC as of version 4.4.
Unfortunately, VC++ 2010 seems to be lagging behind in this respect.
So if you are using an older version of VC++ then you are out of luck...
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.
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!
The following code gives compilation errors on both MSVC++ 2012 CTP (with C+11 support) and Intel C++ XE 13.0:
template <typename F, typename... Args>
void apply(F f, std::tuple<Args...>& args) {
// doesn't do much yet
}
bool f1(char c) {
return c == 'c';
}
int main(int argc, char* argv[]) {
auto t = std::make_tuple('c');
apply(f1, t);
return 0;
}
VS2012 error is:
error C2243: 'type cast' :
conversion from 'std::tuple<char,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil> *'
to 'std::tuple<std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil> &' exists,
but is inaccessible
Error on Intel C++ XE 13.0 is:
error : no instance of function template "apply" matches the argument list
What am I missing? Are there really errors here, or do I just have two bad compilers?
UPDATE: Same (or similar) results when I use boost::tuple instead of std::tuple on both compilers.
ADDENDUM: Thanks for all the cross-checks in the comments. I've sent bug reports to both of these fine corporations.
That is likely a VC11 bug in the implementation of the Standard Library. Although the CTP supports variadic templates, to the best of my knowledge the Standard Library was not rewritten to use them and adopts some machinery to simulate variadic templates. This is likely at the origin of your problem.