I'm updating a huge legacy system, and am currently stumped by the following function:
template <class EL>
EL& FastInsertVector<EL>::operator[](size_type index)
{
return (EL&) FastInsertVectorBase::operator [][](index);
}
MS VC++ 2022 compiles it happily, whereas C++ Builder 11.1.5 rejects it saying:
expected expression
If I remove the second set of [], both compilers are happy. Unfortunately, this is shared code that both compilers must be able to handle.
This codebase is huge, and has no tests, and I'm having difficulty actually understanding what this syntax even means.
Is this valid C++ syntax? Can anyone explain what it's trying to express?
Related
I'm using visual studio 2017 and I noticed that I don't get syntax error warnings when using template, for example:
and when I remove the template I get this:
and this:
Is it possible to fix this?
code(not image):
template<int a>
void noErrors()
{
sleiudbg;sg ojrp jabp srpghs //some gibberish
}
template<int b>
void noErrors(string s)
{
int p = s.Size();
}
Oh please, must we post code only as images? Please fix that, it means I cannot experiment with your code.
But the answer to your question is that the incremental syntax checker built into the IDE is of limited intelligence, especially where templates are concerned (where detecting and reporting compiler errors in general is a complex business) and as a result a great deal of stuff which is not going to compile slips through.
The compiler, on the other hand, will throw this out straightaway, and also report errors resulting from an invalid instantiation of a template in a moderately helpful way (although such error messages are never the easiest things to read).
And can you change any of this? Sorry, no, (unless you can persuade Microsoft to beef-up their IDE).
where error checking is a complex business - more here:
What does a compiler check for uninstantiated template code?
I am trying to test a little C++17. I am trying to do:
[[nodiscard]] int get_value1()
{
return 42;
}
inline void start()
{
// Should generate warning
get_value1();
}
However, it does not. I am using Visual studio 2017. Warning level set to Level4(\W4). I have set C++ Language Standard to ISO C++ Latest Draft Standard (/std:c++latest).
But it does not generate the warning that I want. Why is that? Also, a little side question: That tab to select the language standard only appears in Debug configuration and not Release. Why is that? Release complains on the nodiscard, Would that mean that Release is in C++14?
edit: naturally I meant warning in the second section. Corrected. :)
Actually [[nodiscard]] is supported only since VS 2017.3 and it should give you a warning, not an error. And as I understand specification assumes that compiler may warn you. And may not.
Is there a patch out there (official or unofficial) to get IntelliSense to stop reporting every use of decltype as a syntax error? It compiles fine, so I know decltype is supported, but it's very distracting seeing red squiggles everywhere and makes it much harder to find actual errors in the code. Every compile gives me a list of hundreds of non-errors - basically at least 3 for every use of decltype in the code base, e.g.:
std::for_each(std::begin(list), std::end(list), [](const decltype(list)::value_type& item)
{
<do stuff with item>
});
will produce the following (non) errors:
IntelliSense: global-scope qualifier (leading '::') is not allowed
IntelliSense: expected a ')'
IntelliSense: identifier "item" is undefined
Upgrading to VS2015 is not an option at this point. (I doubt I could convince the company to shell out to upgrade every computer, and upgrading only some of them would lead to backwards compatibility issues.)
Personally, I'd prefer not to use decltype at all until we get an IDE that fully supports it (there's nowhere I know of that you actually need it), but I don't think I can convince everybody of that either. I just want to make all those fake errors go away so that I can find the real ones without poring over thousands of false-positives.
Given a helper template alias
template <typename T> using id = T;
you can avoid the Intellisense errors, while still keeping the code perfectly valid, by writing id<decltype(list)>::value_type where you would otherwise have written decltype(list)::value_type.
Depending on how often decltype is immediately followed by ::, you may want to create a macro as simple as:
#define DECLTYPE(x) id<decltype(x)>
When use Eclipse with MinGW(version:4.8.1) to compile the following code fragement, it can pass but Eclipse still report:
"Multiple markers at this line - Type 'alignas' could not be resolved"
template<typename X> void set_aside(std::vector<X> vx) {
constexpr int max_buf = 1024;
alignas(X) X buffer[max_buf];
int max = min(vx.size(), max_buf / sizeof(X));
std::uninitialized_copy(vx.begin(), vx.begin() + max, buffer);
}
What happend with this issue, although the code fragement pass the comiple,yet Eclipse marks with error.
Someone have ever met this issue? Please kindly help me to resolve this issue,thanks very indeed!
Many IDEs use a front-end syntax checker that is different than their back-end compiler. Eclipse Kepler (released June 2013) is mostly up-to-date with C++11 syntax, although some things like alignment support and the interaction with in-class initializers and default constructors might not be fully supported (yet). Similary, C++14 features like decltype(auto) will work if the back-end compiler is called with std=C++1y but will not be recognized by the front-end syntax checker.
NOTE: this is not unique to Eclipse, also Visual C++ Intellisense is sometimes running behind (especially in CTP versions) the actual compiler, causing the red squiggly lines.
I was surprised to find in Visual Studio 2012 Update 1 the following does not compile anymore:
[](unique_ptr<int>){};
Compiler error states it can't access the private copy constructor of unique_ptr.
The above worked just fine in Visual Studio 2010.
It also compiles just fine in gcc 4.7.2
Is this a known bug, or is this actually expected behavior? I could not find anything on Microsoft Connect.
EDIT: I have just updated to Visual Studio 2012 Update 2, the issue still occurs.
EDIT2: I have filed a bug report on Microsoft Connect, you are welcome to upvote it if it affects you too.
Try this:
int a;
[a](unique_ptr<int>){};
It doesn't matter what it is, just capture something explicitly.
I am still not sure whether this is a bug, it certainly looks like it.
In the meantime, a logical equivalent of
[](unique_ptr<int> aArg)
{
};
can be written as
[](unique_ptr<int> && aArg)
{
unique_ptr<int> arg = std::move(aArg);
};
It's not a very nice approach for me as I am writing library code. The lambda's caller is the library and the lambda is user provided. I do not wish to impose on users that they manually std::move the argument.
So, while this is not practical for me, it might come in handy to someone else.