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
Related
This question already has answers here:
Where and why do I have to put the "template" and "typename" keywords?
(8 answers)
Closed 2 years ago.
I would like to use a static method in a template parameter in my function in an enable_if expression. However, the static method is also a template, and I get compiler errors.
The error message:
$ g++ test.cpp
test.cpp:20:36: error: invalid declarator before ‘(’ token
20 | std::enable_if_t<A::method_a<param>()>
Code sample:
#include <type_traits>
struct B
{
template<int param>
static constexpr int method_a()
{
return param == 5;
}
static constexpr int method_b(int param)
{
return param == 5;
}
};
// this doesn't work
template<int param, typename A>
std::enable_if_t<A::method_a<param>()>
func_a(A& a)
{}
// this works
template<int param, typename A>
std::enable_if_t<A::method_b(param)>
func_b(A& a)
{}
int main()
{
B b;
func_b<5>(b); // this doesn't work
func_a<5>(b); // this works
return 0;
}
In func_a, the name method_a is a dependent name i.e. the meaning of method_a depends on the template type parameter A. If the name is a member template, you need to specify that with the template keyword:
template<int param, typename A>
std::enable_if_t<A::template method_a<param>()>
// ^^^^^^^^
func_a(A& a){}
Here's a demo.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Officially, what is typename for?
Where and why do I have to put the template and typename keywords?
consider the code below:
template<class K>
class C {
struct P {};
vector<P> vec;
void f();
};
template<class K> void C<K>::f() {
typename vector<P>::iterator p = vec.begin();
}
Why is the "typename" keyword necessary in this example?
Are there any other cases where "typename" must be specified?
Short answer: Whenever referring to a nested name that is a dependent name, i.e. nested inside a template instance with unknown parameter.
Long answer: There are three tiers of entities in C++: values, types, and templates. All of those can have names, and the name alone doesn't tell you which tier of entity it is. Rather, the information about the nature of a name's entity must be inferred from the context.
Whenever this inference is impossible, you have to specify it:
template <typename> struct Magic; // defined somewhere else
template <typename T> struct A
{
static const int value = Magic<T>::gnarl; // assumed "value"
typedef typename Magic<T>::brugh my_type; // decreed "type"
// ^^^^^^^^
void foo() {
Magic<T>::template kwpq<T>(1, 'a', .5); // decreed "template"
// ^^^^^^^^
}
};
Here the names Magic<T>::gnarl, Magic<T>::brugh and Magic<T>::kwpq had to be expliciated, because it is impossible to tell: Since Magic is a template, the very nature of the type Magic<T> depends on T -- there may be specializations which are entirely different from the primary template, for example.
What makes Magic<T>::gnarl a dependent name is the fact that we're inside a template definition, where T is unknown. Had we used Magic<int>, this would be different, since the compiler knows (you promise!) the full definition of Magic<int>.
(If you want to test this yourself, here's a sample definition of Magic that you can use. Pardon the use of constexpr in the specializaation for brevity; if you have an old compiler, feel free to change the static member constant declaration to the old-style pre-C++11 form.)
template <typename T> struct Magic
{
static const T gnarl;
typedef T & brugh;
template <typename S> static void kwpq(int, char, double) { T x; }
};
template <> struct Magic<signed char>
{
// note that `gnarl` is absent
static constexpr long double brugh = 0.25; // `brugh` is now a value
template <typename S> static int kwpq(int a, int b) { return a + b; }
};
Usage:
int main()
{
A<int> a;
a.foo();
return Magic<signed char>::kwpq<float>(2, 3); // no disambiguation here!
}
The typename keyword, is needed because iterator is a dependent type on P. The compiler can't guess if iterator refers to a value or a type, so it assume its a value unless you yell typename. It's needed whenever there is a type dependent on a template argument, in a context that either types or values would be valid. For instance, as base classes typename is not needed since a base class must be a type.
On the same subject, there is a template keyword used to let the compiler know that some dependent name is a template function instead of a value.
The typename keyword is needed whenever a type name depends on a template parameter, (so the compiler can 'know' the semantics of an identifier (type or value) without having a full symbol table at the first pass).
Not in the same meaning, and a bit less common, the lone typename keyword can also be useful when using generic template parameters: http://ideone.com/amImX
#include <string>
#include <list>
#include <vector>
template <template <typename, typename> class Container,
template <typename> class Alloc = std::allocator>
struct ContainerTests
{
typedef Container<int, Alloc<int> > IntContainer;
typedef Container<std::string, Alloc<int> > StringContainer;
//
void DoTests()
{
IntContainer ints;
StringContainer strings;
// ... etc
}
};
int main()
{
ContainerTests<std::vector> t1;
ContainerTests<std::list> t2;
t1.DoTests();
t2.DoTests();
}
This question already has answers here:
"invalid use of incomplete type" error with partial template specialization
(5 answers)
Template specialization of particular members?
(2 answers)
Closed 3 years ago.
Why am I getting this error in the following:
template<typename T,typename Y>
class MyContainer
{
std::vector<T> list;
public:
void append( T&& elem) ;
};
template<typename T>
void MyContainer<T,int>::append(T&& elem)
{
list.push_back(elem);
}
int main()
{
}
error: invalid use of incomplete type ‘class >MyContainer’
void MyContainer::append(T&& elem)
I initially thought that, what if someone passed a second template parameter as double, it won't work, so I need to provide a non specialized member function definition first and may be on top of that I can provide partial specialization.
But even after adding the below I still get the same error:
template<typename T, typename Y>
void MyContainer<T,Y>::append(T&& elem)
{
list.push_back(elem);
}
This question already has answers here:
Function template return type deduction
(5 answers)
Closed 4 years ago.
Is it possible to figure out the return type and parameter type of a function and use them as template types? Consider the following example:
template <typename ret, typename in>
class Bar {
// Some code
}
int foo(float x) {
return 0;
}
int main() {
Bar<int, float> b; // Can this be done automatically by inspection of foo at compile time?
}
Can I use the function signature of foo to set the template types of Bar?
Yessir.
template <class Function>
struct BarFor_;
template <class Ret, class In>
struct BarFor_<Ret(*)(In)> {
using type = Bar<Ret, In>;
};
template <auto function>
using BarFor = typename BarFor_<decltype(function)>::type;
Now you can get your type via:
BarFor<foo> b;
See it live on Coliru
As far as I know, you can get the return type of function but you cannot get the type of a function argument (at least in a way you are doing it right now).
This is how you can deduce the return type of a function:
Bar<decltype(foo(1.0)), float> b;
However, you need to pass an argument to the foo function which I think is not what you want.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Officially, what is typename for?
Where and why do I have to put the template and typename keywords?
consider the code below:
template<class K>
class C {
struct P {};
vector<P> vec;
void f();
};
template<class K> void C<K>::f() {
typename vector<P>::iterator p = vec.begin();
}
Why is the "typename" keyword necessary in this example?
Are there any other cases where "typename" must be specified?
Short answer: Whenever referring to a nested name that is a dependent name, i.e. nested inside a template instance with unknown parameter.
Long answer: There are three tiers of entities in C++: values, types, and templates. All of those can have names, and the name alone doesn't tell you which tier of entity it is. Rather, the information about the nature of a name's entity must be inferred from the context.
Whenever this inference is impossible, you have to specify it:
template <typename> struct Magic; // defined somewhere else
template <typename T> struct A
{
static const int value = Magic<T>::gnarl; // assumed "value"
typedef typename Magic<T>::brugh my_type; // decreed "type"
// ^^^^^^^^
void foo() {
Magic<T>::template kwpq<T>(1, 'a', .5); // decreed "template"
// ^^^^^^^^
}
};
Here the names Magic<T>::gnarl, Magic<T>::brugh and Magic<T>::kwpq had to be expliciated, because it is impossible to tell: Since Magic is a template, the very nature of the type Magic<T> depends on T -- there may be specializations which are entirely different from the primary template, for example.
What makes Magic<T>::gnarl a dependent name is the fact that we're inside a template definition, where T is unknown. Had we used Magic<int>, this would be different, since the compiler knows (you promise!) the full definition of Magic<int>.
(If you want to test this yourself, here's a sample definition of Magic that you can use. Pardon the use of constexpr in the specializaation for brevity; if you have an old compiler, feel free to change the static member constant declaration to the old-style pre-C++11 form.)
template <typename T> struct Magic
{
static const T gnarl;
typedef T & brugh;
template <typename S> static void kwpq(int, char, double) { T x; }
};
template <> struct Magic<signed char>
{
// note that `gnarl` is absent
static constexpr long double brugh = 0.25; // `brugh` is now a value
template <typename S> static int kwpq(int a, int b) { return a + b; }
};
Usage:
int main()
{
A<int> a;
a.foo();
return Magic<signed char>::kwpq<float>(2, 3); // no disambiguation here!
}
The typename keyword, is needed because iterator is a dependent type on P. The compiler can't guess if iterator refers to a value or a type, so it assume its a value unless you yell typename. It's needed whenever there is a type dependent on a template argument, in a context that either types or values would be valid. For instance, as base classes typename is not needed since a base class must be a type.
On the same subject, there is a template keyword used to let the compiler know that some dependent name is a template function instead of a value.
The typename keyword is needed whenever a type name depends on a template parameter, (so the compiler can 'know' the semantics of an identifier (type or value) without having a full symbol table at the first pass).
Not in the same meaning, and a bit less common, the lone typename keyword can also be useful when using generic template parameters: http://ideone.com/amImX
#include <string>
#include <list>
#include <vector>
template <template <typename, typename> class Container,
template <typename> class Alloc = std::allocator>
struct ContainerTests
{
typedef Container<int, Alloc<int> > IntContainer;
typedef Container<std::string, Alloc<int> > StringContainer;
//
void DoTests()
{
IntContainer ints;
StringContainer strings;
// ... etc
}
};
int main()
{
ContainerTests<std::vector> t1;
ContainerTests<std::list> t2;
t1.DoTests();
t2.DoTests();
}