The best I can determine is that symbols defined in the parent class are no longer carried into the child class by default. This is counter to the way I've always believed C++ to work.
template<typename T>
class Parent
{
public:
typedef T* iterator;
};
template<typename T>
class Child : public Parent < T >
{
public:
//using iterator = Parent<T>::iterator; // this fixes error C3646 and error C2059
iterator begin(void)
{
return nullptr;
}
};
1>Test1.cpp(14,1): error C3646: 'begin': unknown override specifier
1>Test1.cpp(18): message : see reference to class template instantiation 'Child<T>' being compiled
1>Test1.cpp(14,16): error C2059: syntax error: '('
1>Test1.cpp(15,1): error C2334: unexpected token(s) preceding '{'; skipping apparent function body
This started happening when I changed the file settings to use C++14 or C++17, prior to that it was OK. There appears to be no way to restore the prior behavior, even selecting "Default" generates the errors. It still works fine in Visual Studio 2013.
Related
I am working on Visual Studio 2015 community edition.
The following code produces an error:
#include <list>
using std::list;
template <typename T>
class enumerator
{
// typedef:
public:
using list_ = list<T*>; // line:
using list_fwd_c = list_::const_iterator; // 188
using list_fwd = list_::iterator; // 189
using list_rvs_c = list_::const_reverse_iterator; // 190
using list_rvs = list_::reverse_iterator; // 191
}; // 192
and the error:
1>d:\develop\workspace\visual_studio\nevada_test_site\source\shared\cpp\expression_evaluator\expression_evaluator\src\expr_eval.cpp(188): error C2061: syntax error: identifier 'const_iterator'
1> d:\develop\workspace\visual_studio\nevada_test_site\source\shared\cpp\expression_evaluator\expression_evaluator\src\expr_eval.cpp(192): note: see reference to class template instantiation 'cpplib::eval::utils::enumerator<T>' being compiled
1>d:\develop\workspace\visual_studio\nevada_test_site\source\shared\cpp\expression_evaluator\expression_evaluator\src\expr_eval.cpp(188): error C2238: unexpected token(s) preceding ';'
1>d:\develop\workspace\visual_studio\nevada_test_site\source\shared\cpp\expression_evaluator\expression_evaluator\src\expr_eval.cpp(189): error C2061: syntax error: identifier 'iterator'
1>d:\develop\workspace\visual_studio\nevada_test_site\source\shared\cpp\expression_evaluator\expression_evaluator\src\expr_eval.cpp(189): error C2238: unexpected token(s) preceding ';'
1>d:\develop\workspace\visual_studio\nevada_test_site\source\shared\cpp\expression_evaluator\expression_evaluator\src\expr_eval.cpp(190): error C2061: syntax error: identifier 'const_reverse_iterator'
1>d:\develop\workspace\visual_studio\nevada_test_site\source\shared\cpp\expression_evaluator\expression_evaluator\src\expr_eval.cpp(190): error C2238: unexpected token(s) preceding ';'
1>d:\develop\workspace\visual_studio\nevada_test_site\source\shared\cpp\expression_evaluator\expression_evaluator\src\expr_eval.cpp(191): error C2061: syntax error: identifier 'reverse_iterator'
1>d:\develop\workspace\visual_studio\nevada_test_site\source\shared\cpp\expression_evaluator\expression_evaluator\src\expr_eval.cpp(191): error C2238: unexpected token(s) preceding ';'
I have confirmed this is the troublesome code piece (error disappear when I comment out the 'enumerator' class).
As its name suggests, it "will be" a simple enumerator class (something like a IEnumerator from C#. I will use it in order to store a list of objects derived from a base class passed as a class template parameter T.
Question:
1. Why the code above produces this error.
2. How can I fix this error?
3. I know this is not a place for this, but if you know a good implementation (boost ?) for this kind of enumerator, please point me in the right direction.
You still need to add a typename despite how convenient using is:
using list_fwd_c = typename list_::const_iterator; // 188
using list_fwd = typename list_::iterator; // 189
using list_rvs_c = typename list_::const_reverse_iterator; // 190
using list_rvs = typename list_::reverse_iterator; // 191
The problem is that these are dependent types (they depend on the template parameter) so the compiler cannot just know they are all types (and not, say functions or static data members)
In a CDialog class I needed to override
Using VS2008 I've done this several times before using the IDE properties/override and it adds adding this code:
virtual BOOL PreTranslateMessage(MSG* pMsg); // in the header file
BOOL CMyTestDlg::PreTranslateMessage(MSG* pMsg) // in the cpp file
{
return CDialog::PreTranslateMessage(pMsg);
}
The compiler complains with these messages:
error C2059: syntax error : 'constant'
error C2065: 'pMsg' : undeclared identifier
error C2448: 'CMy_TestDlg::PreTranslateMessage' : function-style initializer appears to be a function definition
If I removed the PreTranslateMessage stuff the project compiles and runs as expected.
As the IDE added the override code I'm confused as to what I did wrong, so
I made another simpler Project and did the override in it, and it compiles OK.
In VC++ 2015 I have an untemplated class which should have a templated memberfunction which returns a map.
Here is a bit of the code:
class Registry
{
template<class configclass>
std::map<std::wstring, configclass> enumerateSubKeys(std::wstring subKeyName);
}
But the compiler throws error messages:
error C2988: Unrecognized template declaration/definition
error C2143: Syntax error: missing ";" before "<"
error C2238: Unexpected Token before ";"
error C2059: Syntax error: "<"
I assume my problem is in having to use a map where the wstring has to be fixed/untemplated but the second argument is my template class.
Of course i followed the compilers suggestions but that didn't get me any further.
You need to #include <map> and add a semi-colon to the end of your class declaration.
As #Kevin and #juanchopanza have pointed out in the comments, you are simply missing a semi-colon and potentially an include. With the following program in VS2013:
class Registry
{
template<class configclass>
std::map<std::wstring, configclass> enumerateSubKeys(std::wstring subKeyName);
}
int main()
{
}
I get an assortment of the errors you listed:
error C2143 : syntax error : missing ';' before '<'
error C2238 : unexpected token(s) preceding ';'
error C2988 : unrecognizable template declaration / definition
error C2059 : syntax error : '<'
And also:
error C2039 : 'map' : is not a member of 'std'
Once I add an include for std::map, the errors are reduced:
#include <map>
class Registry
{
template<class configclass>
std::map<std::wstring, configclass> enumerateSubKeys(std::wstring subKeyName);
}
error C2628 : 'Registry' followed by 'int' is illegal(did you forget a ';' ? )
Which suggests you are missing a semi-colon at the end of the class declaration.
Consider this code snippet:
void Foo(std::string str1, std::string str2) {}
template<typename... Types>
void Bar()
{
Foo(Types{}...); // wont compile
}
Bar<std::string, std::string>();
What I want to do here is to default construct two std::string objects inside the Bar method and pass them to Foo. However my vain attempts (one of them being in the snippet) wont compile so I am wondering whether this is even possible.
I compiled with VC 2013, which throws compiler errors at me. As stated in the comments, other compilers can handle it. Can anyone tell whether the above snippet is standard conform?
It's a problem in the MSVC variadic template expansion process; when it unpacks the list of types it fails to recognise them as suitable for a constructor call. As a workaround, you can perform a type transformation to force the compiler to recognise them:
template<typename T> using identity_t = T; // NEW CODE
void Foo(int, int);
template<typename... Types>
void Bar()
{
Foo(identity_t<Types>{}...); // use identity type transformation
}
int main() {
Bar<int, int>();
}
I haven't managed to find an issue number yet.
This crashes the VC 2013 compiler for me. The errors seem to indicate that it has some problems parsing the code. So when the compiler crashes it must be a compiler bug.
1>main.cpp(23): error C2144: syntax error : 'std::string' should be preceded by ')'
1> main.cpp(28) : see reference to function template instantiation 'void Bar<std::string,std::string>(void)' being compiled
1>main.cpp(23): error C2660: 'Foo' : function does not take 0 arguments
1>main.cpp(23): error C2143: syntax error : missing ';' before '{'
1>main.cpp(23): error C2143: syntax error : missing ';' before ','
1>c1xx : fatal error C1063: INTERNAL COMPILER ERROR
1> Please choose the Technical Support command on the Visual C++
1> Help menu, or open the Technical Support help file for more information
1>cl : Command line warning D9028: minimal rebuild failure, reverting to normal build
1>
1>Build FAILED.
I was implementing boost::intrusive for one of my project on visual C++ 2008 and i stumbled upon a problem. i am using splay hooks for splay_multiset containers. I have defined splay hook publically under MyClass (code below).
#include <boost/intrusive/unordered_set.hpp>
#include <boost/intrusive/splay_set.hpp>
#include <iostream>
using namespace boost::intrusive;
class MyClass
{
int int_;
public:
MyClass(int i)
: int_(i)
{}
splay_set_member_hook<link_mode<normal_link> > memberSplayHook;
//**OPTION-1**
//PROBLEM CODE SEGMENT ++
//typedef member_hook<MyClass, splay_set_member_hook<link_mode<normal_link> >, &MyClass::memberSplayHook> MemberOption;
//typedef splay_multiset<MyClass, MemberOption> MemberMultiSet;
//PROBLEM CODE SEGMENT --
MemberMultiSet mmset;
};
//**OPTION-2**
//WORKING CODE SEGMENT ++
typedef member_hook<MyClass, splay_set_member_hook<link_mode<normal_link> >, &MyClass::memberSplayHook> MemberOption;
typedef splay_multiset<MyClass, MemberOption> MemberMultiSet;
//WORKING CODE SEGMENT --
int main()
{
return 0;
}
The problem is, to use splay_multiset, whatever option i choose (either option-1 or 2, mention in code), in both cases i see compilation errors.
When Option-1 is enabled (option-2 is commented), i see errors below:
1>d:\projects\sampleproject\sample.cpp(21) : error C2327: 'MyClass::memberSplayHook' : is not a type name, static, or enumerator
1>d:\projects\sampleproject\sample.cpp(21) : error C2065: 'memberSplayHook' : undeclared identifier
1>d:\projects\sampleproject\sample.cpp(22) : error C3203: 'member_hook' : unspecialized class template can't be used as a template argument for template parameter 'O1', expected a real type
While, when Option-2 is enabled (option-1 is commented out), i dont see undeclared identifier error msg as these errors coming with option-1. But i do see errors like below (which are obvious).
1>d:\projects\sampleproject\sample.cpp(25) : error C2146: syntax error : missing ';' before identifier 'mmset'
1>d:\projects\sampleproject\sample.cpp(25) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
My question is why i am getting error in first case? What can i do to get pass this issue?
Boost member hooks have (always?) been broken, since they don't compile with Visual C++.
I don't have a VS at hand to check for the precise error message so I might be wrong (but reading 'member hooks' and 'Visual C++' always triggers 'there's a problem'-mode), but do try to check this:
http://permalink.gmane.org/gmane.comp.lib.boost.user/56875
EDIT: Don't take the headline literally -- the same applies to Visual C++ 2010 and 2012. All my member hooks use this workaround; at some point I might even try to understand what it does, or more importantly, how to package it into a more comfortable setup for less "I need to find a previous implementation of this workaround so I can copy-and-modify it"...