How to get this template class to compile? - c++

Sorry, I couldn't frame a question that could capture my problem properly. My problem is this.
I have a templated class like this. I am not able to understand how exactly to define the Get function.
template<class Data>
class Class
{
struct S
{
};
void Do();
S Get();
};
template<class Data>
void Class<Data>::Do()
{
}
template<class Data>
Class<Data>::S Class<Data>::Get()
{
}
I get the following errors
1>error C2143: syntax error : missing ';' before 'Class<Data>::Get'
1>error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>fatal error C1903: unable to recover from previous error(s); stopping compilation

template<class Data>
Class<Data>::S Class<Data>::Get()
needs to be
template<class Data>
typename Class<Data>::S Class<Data>::Get()
because S is a dependent type. Any time you have a type that's nested in a template you need to use the keyword typename. For example, an iterator over a vector<int> has the type typename vector<int>::iterator.

A C++11 style, easier to read and write :
template<class Data>
auto Class<Data>::Get() -> S {
return {};
}

Related

template alias in specialized class

The following code gives the error (in line where i define test):
error C2143: syntax error: missing ';' before '<'
note: see reference to class template instantiation 'ptc::Produce' being compiled
error C4430: missing type specifier - int assumed.
Note: C++ does not support default-int
Does anybody know why this happens?
Compiler is VC2015 CTP1.
Edit: the error must happen in phase1 of the template parsing, because it occurs even I never instantiate the class Produce.
namespace OrderPolicy
{
struct Unordered {};
struct Ordered {};
};
template <typename TOrderPolicy>
struct OrderManager {};
template<>
struct OrderManager<OrderPolicy::Unordered>
{
template <typename TItem>
using item_t = TItem;
};
template<>
struct OrderManager<OrderPolicy::Ordered>
{
template <typename TItem>
using item_t = TItem*;
};
template<typename TOrderPolicy>
struct Produce : public OrderManager<TOrderPolicy>
{
item_t<int> test;
//using item_type = item_t<int>;
};
Edit2: it works when I change the last part of the code to
struct Produce : public OrderManager<OrderPolicy::Ordered>
{
item_t<int> test;
//using item_type = item_t<int>;
};
item_t<int> test;
That names a dependent template type from a base class. In this case, you need to tell the compiler both that item_t is a type in your base class, and that it's a template.
The direct way to do this is using typename and template:
typename OrderManager<TOrderPolicy>::template item_t<int> test;
As you can see, this will quickly become unreadable. I would make some local aliases to make the code neater:
using Base = OrderManager<TOrderPolicy>;
using item_type = typename Base::template item_t<int>;
item_type test;
You'll have to use:
typename OrderManager<TOrderPolicy>::template item_t<int>
in place of:
item_t<int> test;
wow, learning never stops. Until now I did not see the keyword template used in this context.

Wrapper for std::queue emplace

I'm working with Visual Studio 2012 on Windows 8 and trying to create a wrapper for std::queue which adds thread safety and a few other features. I'm having trouble creating a wrapper function for emplace. I suspect it's due to the way variadic templates are emulated, but I"m not sure how to fix it.
template <typename T>
class MyQueue
{
public:
template <class... Args> // line 20
void emplace(Args&&... args)
{
mQueue.emplace(std::forward<Args>(args)...);
}
private:
std::queue<T> mQueue;
};
This code gives me a bunch of syntax errors.
# line 20:
C2011: '' : 'enum' type redefinition
C2143: syntax error : missing ',' before '...'
C2332: 'class' : missing tag name
# line 21:
C2059: syntax error : '...'
C2065: 'Args' : undeclared identifier
Is there any clean way to tap into the underlying queue's emplace function? I'm not doing anything performance critical so if it ends up being more trouble than it's worth I'll just force callers to use push.
Any solutions must be with VC++11 - switching platforms or compilers is not an option for me.
I ended up getting this to work by changing the Platform Toolset to the Nov 2012 CTP in the project settings. As others pointed out - the code itself was correct. See below for a simple example.
MyQueue.h:
#pragma once
#include <queue>
template <typename T>
class MyQueue
{
public:
template <class... Args>
void emplace(Args&&... args);
private:
std::queue<T> mQueue;
};
template <typename T>
template <class... Args>
void MyQueue<T>::emplace(Args&&... args)
{
mQueue.emplace(std::forward<Args>(args)...);
}
Main.cpp
#include "MyQueue.h"
struct Test
{
int mA, mB;
Test(int a, int b) : mA(a), mB(b) { }
};
int main()
{
MyQueue<Test> q;
q.emplace(1, 1);
q.emplace(2, 2);
q.emplace(3, 3);
return 0;
}

typedef for template inside template [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Where and why do I have to put the “template” and “typename” keywords?
I have a class that creates a smart pointer when creating a object and passing the desired class as template parameter. And I have another class that needs to use that smart pointer in another class.
#include <iostream>
using namespace std;
//smart pointer class
template<typename T>
class IntrusivePtr
{
public:
IntrusivePtr()
{
cout << "IntrusivePtr()";
}
};
//class for which I need a smart pointer which is also template
template<typename T>
class A
{
public:
A()
{
cout << "A()";
}
typedef IntrusivePtr< A<T> > my_ptr;
};
//class that uses the smart pointer.
template<typename T>
class B
{
public:
B()
{
cout << "B()";
}
typedef A<T>::my_ptr x;
};
int main()
{
B<int> ob;
return 0;
}
Can this be achieved in c++?
I know the new C++11 supports typedefs for things like this but I'm using the old standard :(
Compiling this I'm getting some bad ass errors:
C:\Users\jacob\typedef_template_class-build-desktop-Qt_4_8_1_for_Desktop_-_MSVC2008__Qt_SDK__Debug..\typedef_template_class\main.cpp:41:
error: C2146: syntax error : missing ';' before identifier 'x'
C:\Users\jacob\typedef_template_class-build-desktop-Qt_4_8_1_for_Desktop_-_MSVC2008__Qt_SDK__Debug..\typedef_template_class\main.cpp:41:
error: C2146: syntax error : missing ';' before identifier 'x'
C:\Users\jacob\typedef_template_class-build-desktop-Qt_4_8_1_for_Desktop_-_MSVC2008__Qt_SDK__Debug..\typedef_template_class\main.cpp:41:
error: C4430: missing type specifier - int assumed. Note: C++ does not
support default-int
EDIT:
Sorry, I changed some things and the error code. This is how I want it to be. Sorry
template<typename T>
class B
{
public:
B()
{
cout << "B()";
}
typedef typename A< B >::my_ptr x;
};
You should use typename, since my_prt is dependent name.
Your problem is that A<B>::my_ptr is a dependend name (it depends on B<T> and therefore on the template parameter T). For this reason the compiler doesn't know if it is supposed to be a type or a variable when parsing the template. In that situation it assumes that my_ptr is not a type, unless you explecitely tell it so. Therefore you need to add typename, just like the compiler told you to do:
typedef typename A< B >::my_ptr x;
For a more complete explanation look at this answer to a similar question.

C++ templates and structs problem

I have this...
template <typename Key, typename Value>
class A {
public:
//...
private:
struct MyStruct{
Key key;
Value value;
};
};
And it gives me the following errors:
Error 1 error C2146: syntax error : missing ';' before identifier 'value'
Error 2 error C4430: missing type specifier - int assumed.
Error 3 error C4430: missing type specifier - int assumed.
Some specs:
Using Visual Studio 2010
Windows 7 x64
Can my error be before or after these lines?
You forgot a semicolon after the class definition, at the very end of your code.
In some cases you need to write typename Key key; instead of a simple Key key; in templates, since the compiler may not know that Key is really a typename. So try this:
template <typename Key, typename Value>
class A {
public:
//...
private:
struct MyStruct {
/* typename not allowed here */ Key key;
/* typename not allowed here */ Value value;
};
};
You forgot the last semi-colon to end your class definition.
It looks like you missed a semi-colon to close out your class.
This compiles fine for me using g++ 4.6.1:
#include <iostream>
template <typename Key, typename Value>
class A {
public:
A() {}
private:
struct MyStruct {
Key key;
Value value;
};
};
int main(void) {
A<int, char> a;
}
First, maybe it's just a typo in the code you pasted, but you are missing the ; at the end of the class definition.
Beyond that, I don't see a problem. Make sure you are declaring an object as
A<type, type> a;
What are you using for your template types?

Coding iterator function for STL Class

I am working through some C++ code from "Financial Instrument Pricing Using C++" - a book on option pricing using C++. Following code is a small snippet stripped of many details which basically attempts to define a SimplePropertySet class that is intended to contain a name and list.
#include <iostream>
#include <list>
using namespace::std;
template <class N, class V> class SimplePropertySet
{
private:
N name; // The name of the set
list<V> sl;
public:
typedef typename list<V>::iterator iterator;
typedef typename list<V>::const_iterator const_iterator;
SimplePropertySet(); // Default constructor
virtual ~SimplePropertySet(); // Destructor
iterator Begin(); // Return iterator at begin of composite
const_iterator Begin() const;// Return const iterator at begin of composite
};
template <class N, class V>
SimplePropertySet<N,V>::SimplePropertySet()
{ //Default Constructor
}
template <class N, class V>
SimplePropertySet<N,V>::~SimplePropertySet()
{ // Destructor
}
// Iterator functions
template <class N, class V>
SimplePropertySet<N,V>::iterator SimplePropertySet<N,V>::Begin()//<--this line gives error
{ // Return iterator at begin of composite
return sl.begin();
}
int main(){
return(0);//Just a dummy line to see if the code would compile
}
On compiling this code on VS2008, I obtain the following errors:
warning C4346: 'SimplePropertySet::iterator' : dependent name is not a type
prefix with 'typename' to indicate a type
error C2143: syntax error : missing ';' before 'SimplePropertySet::Begin'
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
Is there something stupid or basic that I am getting wrong or forgetting here? Is it a syntax error? I am unable to put my finger on it. The book from which this code snippet is taken says their code was compiled on Visual Studio 6. Is this some version-related issue?
Thanks.
As indicated by the compiler, you must replace :
template <class N, class V>
SimplePropertySet<N,V>::iterator SimplePropertySet<N,V>::Begin()
with :
template <class N, class V>
typename SimplePropertySet<N,V>::iterator SimplePropertySet<N,V>::Begin()
See this link for an explanation on dependent names.