This question already has answers here:
Where and why do I have to put the "template" and "typename" keywords?
(8 answers)
Closed 9 years ago.
I'm trying to do something like this:
#include <iostream>
#include <array>
using namespace std;
template <size_t A>
class Test {
public:
typedef array<int, A> TestType;
};
template <size_t A>
void foo(Test<A>::TestType t) {
cout << "test\n";
}
int main() {
Test<5>::TestType q;
foo(q);
return 0;
}
but foo doesn't compile. In gcc I get
prog.cpp:12:19: error: variable or field ‘foo’ declared void
void foo(Test<A>::TestType t) {
^
prog.cpp:12:28: error: expected ‘)’ before ‘t’
void foo(Test<A>::TestType t) {
while in Visual Studio 2010 I get
error C2975: 'Test' : invalid template argument for 'A', expected compile-time constant expression
I don't understand what I am doing wrong, as A is a compile-time constant. What should I change?
If you would add typename like this:
template <size_t A>
void foo(typename Test<A>::TestType t) {
cout << "test\n";
}
the only effect is a better error message. The problem is that you still can not deduce template parameters like that.
When you declare q
Test<5>::TestType q;
q's type is std::array<int,5> and the compiler doesn't know how this type was connected to Test<5>. In the call to foo(q) it would need a much deeper analysis of the code which is not standardized to figure out that there is only one possible match for A. You need to call
foo<5>(q);
to specify it explicitly or change the definition of foo:
template <size_t A>
void foo(std::array<int,A> t) {
cout << "test\n";
}
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:
"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:
Where and why do I have to put the "template" and "typename" keywords?
(8 answers)
Closed 6 years ago.
Compiler: TDM-GCC 5.1.0 (SJLJ Unwinding)
I'm having an issue passing variable number of type arguments to a static variadic template method call inside of a template function. I've tried every syntax variation, but it won't compile, so I can only assume I'm doing this wrong.
Here's the setup:
#include <iostream>
template <class T>
struct Foo
{
template <class...>
static void test()
{
std::cout << "Foo<T>::test<...>() called.";
}
};
template <class T, class... Args>
void bar()
{
Foo<T>::test<Args...>(); //error happens here
}
int main()
{
bar<int, int>();
}
This gives the compiler error: expected primary-expression before '...' token.
I thought pack expansions looked like Args..., but that doesn't seems to work here.
Any help is appreciated.
You need to tell the parser that dependant test is a template:
template <class T, class... Args>
void bar()
{
Foo<T>::template test<Args...>(); //error happens here
^^^^^^^^^
}
demo
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.
To put it somewhat vaguely, from the snippet (tt.cc) below it seems to me as if the template template notion lacked some kind of a "transparency". While I don't seem to fathom what other template argument should A::f() be provided (besides the template template one), I might as well be just missing some banality here.
template <class T>
class A {
public:
template< template<class> class U >
void f( int i ) {
// ...
}
};
template< class T, template<class> class U >
class B {
public:
void f( int i ) {
A<T> a;
a.f<U>( i );
}
};
int main() {
return 0;
}
The error message it provides is:
g++ ./tt.cc -o tt
./tt.cc: In member function ‘void B<T, U>::f(int)’:
./tt.cc:17:10: error: missing template arguments before ‘>’ token
a.f<U>( i );
^
Compilation exited abnormally with code 1
Any ideas greatly appreciated.
What you are seeing is the compiler interpreting the > token inside f<U> as the inequality operator. You need to add .template to let the compiler know you mean a template argument.
void f( int i ) {
A<T> a;
a.template f<U>( i );
}
Live Example.
See also Where and why do I have to put the “template” and “typename” keywords?.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is it possible to emulate template<auto X>?
Consider the following working code:
#include <iostream>
template<typename T> struct Traits {};
template<typename T, typename A>
struct Traits<void(T::*)(A)>
{
typedef T Class;
typedef A Arg;
};
template<typename T, typename U, void(T::*MemFun)(U)>
void Builder()
{
std::cout << typeid(T).name() << std::endl;
std::cout << typeid(U).name() << std::endl;
std::cout << typeid(MemFun).name() << std::endl;
}
template<typename T, T arg>
void Builder()
{
return Builder<Traits<T>::Class,Traits<T>::Arg,arg>();
}
class Class
{
public:
void foo(int) { }
};
int main()
{
Builder<decltype(&Class::foo), &Class::foo>();
}
What I'd like to be able to do is something like this to get the same result, without using a macro.
int main()
{
Builder<&Class::foo>();
}
I can't seem to create a template that takes the pointer to member and deduces the type. Any thoughts? The pointer to member must be used as a template argument as opposed to a function parameter because it's used to create a template function (not shown).
Cannot be done. To have a non-type template argument you must provide the type. So either you limit your Builder to only one particular type or else you need an extra argument (first in the list) that is the type of second argument. Now, if you are willing not to use the member pointer as a constexpr... that is simple.
template <typename T, typename M>
struct Builder {
M T::*ptr;
Builder( M T::*ptr ) : ptr(ptr) {}
};
template <typename T, typename M>
Builder<T,M> createBuilder( M T::*ptr ) {
return Builder<T,M>(ptr);
}
int main() {
auto bld = createBuilder( &Class::member );
}
I have spent some time trying to do a similar thing myself.
I don't think it is possible without using the name of the function Class::foo twice. My reasoning is as follows:
to get the type of foo we must either use decltype or give foo as an argument to a template function
in any of the above, the constexpr-ness of foo (allowing it to be used as a template argument) is lost
moreover, we cannot "duplicate" foo inside a template class or function, as it would face the same problem as above
conclusion: we have to type foo twice at the outer scope
It seems one cannot get away without "dirty" macro tricks, even in C++11...
Unfortunately there's no way to do type deduction for the type of non-type template parameters. A macro is really the only option here.