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?
#include <iostream>
using namespace std;
template <class T>
class Test
{
union obj
{
union obj* next;
int num;
};
static const int SZ=3;
static obj* volatile list[SZ];
};
template <class T>
Test<T>::obj* volatile
Test<T>::list[SZ]=
{
0, 0, 0
};
int main()
{
return 0;
}
With g++, the error I get is:
18|error: expected constructor, destructor, or type conversion before '*' token
Add the keyword typename before Test<T>::obj* in the definition of the member.
Related
This question already has answers here:
Derived template-class access to base-class member-data
(3 answers)
Why doesn't a derived template class have access to a base template class' identifiers?
(4 answers)
Why do I have to access template base class members through the this pointer?
(3 answers)
Closed 3 years ago.
Why using std::conditional prevents a child struct to access public members of a parent struct? As a case in point, the following program doesn't compile, complaining that a is not defined. What would be the right way to fix this?
template <int i>
struct mtmd_A {
static constexpr int a = i;
};
template <int i>
struct mtmd_B {
static constexpr int a = i * i;
};
template <bool select>
struct mtmd: public std::conditional<select, mtmd_A<17>, mtmd_B<17>>::type {
static constexpr int b = a;
};
int main()
{
std::cout << mtmd<true>::b << std::endl;
}
Edit
This doesn't seem to be a duplicate of this question since the problem appears only when I add std::conditional.
This question already has answers here:
Where and why do I have to put the "template" and "typename" keywords?
(8 answers)
Nested templates with dependent scope
(1 answer)
Closed 7 years ago.
The following code fails to compile with the following error:
Error C2923 'std::map': 'Foo::CacheEntry' is not a valid
template type argument for parameter '_Ty'
Why is Foo::CacheEntry not a valid template type argument?
#include "stdafx.h"
#include <iostream>
#include <map>
#include <string>
template<int arga>
class Foo {
private:
class CacheEntry {
public:
int x;
};
static std::map<std::string, CacheEntry> cache;
};
template<int argb>
std::map<std::string, Foo<argb>::CacheEntry> Foo<argb>::cache = std::map<std::string, Foo<argb>::CacheEntry>();
Foo<argb>::CacheEntry is a dependent name, so you need to tell the compiler that it names a type with the typename keyword:
template<int argb>
std::map<std::string, typename Foo<argb>::CacheEntry> Foo<argb>::cache{};
Note that the copy-initialization is pretty redundant, you can just use value-initialization.
If you find yourself needing that type a fair amount, you can make an alias for it:
template<int arga>
class Foo {
private:
class CacheEntry {
public:
int x;
};
using CacheMap = std::map<std::string, CacheEntry>;
static CacheMap cache;
};
template<int argb>
typename Foo<argb>::CacheMap Foo<argb>::cache {};
This question already has answers here:
Where and why do I have to put the "template" and "typename" keywords?
(8 answers)
Closed 8 years ago.
I am trying to defing a table of function pointers that can be searchable by string.
I defined the following template class but I have trouble with the static member.
The error I have is
test.cpp:18: error: expected constructor, destructor, or type conversion
before ‘Attribute’
Even If a add a constructor it doesn't work: do you know what's the reason the compiler is telling me that and what is missing from this simple piece of code?
#include<iostream>
#include<map>
#include<boost/function.hpp>
using namespace std;
using namespace boost;
template<class T>
class Attribute {
public:
typedef map<string, boost::function<void(T*,string) > > Params;
static Params params_;
};
template<class T>
T::Params Attribute<T>::params_;
Can you help me?
You need typename before T::Params.
template<class T>
class Attribute
{
public:
typedef map<string, boost::function<void(T*,string) > > Params;
static typename T::Params params_;
^^^^^^^^^^^^
};
template<class T>
typename T::Params Attribute<T>::params_;
^^^^^^^^
Or...
template<class T>
class Attribute
{
public:
typedef map<string,int > Params;
static Params params_;
};
template<class T>
typename Attribute<T>::Params Attribute<T>::params_;
^^^^^^^^^^^^^^^^^^^^^^^
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 want to create a template which takes a type T and a parameter N as arguments and 'gives' a pointer of Nth grade for T(eg. if T is int and N is 2 it should give int**)
My code so far is:
template<class T,int N>
struct ptr
{
typedef ptr<T*,N-1>::t t;
};
template<class T>
struct ptr<T,0>
{
typedef T t;
};
int main()
{
ptr<int,3>::t a; //a should be int***
}
But it gives me this compiler error:
source.cpp:6:11: error: need 'typename' before 'ptr<T*, (N - 1)>::t' because 'ptr<T*, (N - 1)>' is a dependent scope
What does this mean and how can it be fixed(if its possible in C++)?
The error means that ptr<T*, (N - 1)>::t is a dependent name.
The meaning of t used in a template definition depends upon the template parameters, so the compiler cannot automatically determine that t is a type and not an object.
To correct the error, you have to give the compiler a hint, i.e. to do literally what the message suggests: prefix it with typename
typedef typename ptr<T*,N-1>::t t;
template<class T,int N>
struct ptr
{
typedef typename ptr<T*,N-1>::t t;
};
template<class T>
struct ptr<T,0>
{
typedef T t;
};
int main()
{
ptr<int,3>::t a; //a should be int***
}
Compiler tells that t is dependent name, so use typename before ptr<T*, (N - 1)>::t
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
C++ Restrict Template Function
Is it possible to write a C++ template to check for a function's existence?
Is it possible to restrict the types for which a template may be instantiated
(that is, have a compiler error if I use template<type_not_allowed>)?
One way would be to provide no default implementation, and specialize your class template only on those types you wish to allow. For example:
#include <iostream>
using namespace std;
template<class X> class Gizmo
{
public:
Gizmo();
};
template<> Gizmo<int>::Gizmo()
{
}
int main()
{
Gizmo<float> gf; // ERROR: No specialization for Gizmo<float> results in a linking error
}
Make the constructor private in the illegal type:
template<typename T>
class Z
{
public:
Z() {}
};
template<>
class Z<int>
{
private:
Z();
};
Z<float> f; // OK
Z<int> i; // Compile time error.