Two templates in C++: "expected primary-expression before ‘>’ token" [duplicate] - c++

This question already has answers here:
Where and why do I have to put the "template" and "typename" keywords?
(8 answers)
Closed 7 years ago.
Minmal working example:
#include <iostream>
struct Printer
{
template<class T>
static void print(T elem) {
std::cout << elem << std::endl;
}
};
template<class printer_t>
struct Main
{
template<class T>
void print(T elem) {
// In this case, the compiler could guess T from the context
// But in my case, assume that I need to specify T.
printer_t::print<T>(elem);
}
};
int main()
{
Main<Printer> m;
m.print(3);
m.print('x');
return 0;
}
My compiler (g++) gives me the error "expected primary-expression before ‘>’ token". What's wrong and how to fix it?
C++11 accepted.

clang gives a better error message in this case:
$ clang++ example.cpp -o example
example.cpp:18:20: error: use 'template' keyword to treat 'print' as a dependent template name
printer_t::print<T>(elem);
^
template
1 error generated.
Just add the template where it says to, and you're set.

Related

C++ variadic template syntax within dependent scope

I have a problem with real-world code and have replicated the problem with the following sample code.
#include <iostream>
#include <tuple>
using namespace std;
struct Identity
{
template <typename... T>
static std::tuple<T...> Apply(T... val)
{
return std::tuple(val...);
}
};
template <typename F, typename... T>
std::tuple<T...> Apply(T... t)
{
return F::Apply<T...>(t...);
}
int main()
{
const auto t = Apply<Identity>(1., 2., 3.);
cout << std::get<0>(t);
cout << std::get<1>(t);
cout << std::get<2>(t);
return 0;
}
Compilation error:
main.cpp:26:22: error: expected primary-expression before ‘...’ token
return F::Apply<T...>(t...);
^~~
main.cpp:26:22: error: expected ‘;’ before ‘...’ token
main.cpp:26:22: error: expected primary-expression before ‘...’ token
If I remove <T...> from the problematic statement, i.e. return F::Apply(t...);, and let the compiler deduce the type, it works. However, in my real world code I need to specify the types. What is the correct syntactical sugar to specific the types and satisfy the compiler?
You are missing one keyword. You need:
return F::template Apply<T...>(t...);
And it'll be fine. This error message is not the clearest one. :)
You can find an explanation here if you are interested in the details:
Where and why do I have to put the "template" and "typename" keywords?

C++ parameter pack usage [duplicate]

This question already has answers here:
Where and why do I have to put the "template" and "typename" keywords?
(8 answers)
Closed 1 year ago.
I want to encapsulate a class which uses template parameter pack and function template into another similar class, like the following example:
#include <iostream>
template<typename ... Args>
struct O2 {
template<int T>
void f() {
}
};
template<typename ... Args>
struct O1 {
O2<Args...> i2;
template<int T>
void g() {
i2.f<T>();
}
};
int main()
{
O1<int> i1;
i1.g<1>();
return 0;
}
but the compliler it says I'm wrong:
main.cpp: In member function 'void O1<Args>::g()':
main.cpp:18:17: error: expected primary-expression before ')' token
18 | i2.f<T>();
| ^
main.cpp: In instantiation of 'void O1<Args>::g() [with int T = 1; Args = {int}]':
main.cpp:25:12: required from here
main.cpp:18:13: error: invalid operands of types '<unresolved overloaded function type>' and 'int' to binary 'operator<'
18 | i2.f<T>();
| ~~~~^~
I can't modify the inner class (O2), and I can't use inheritance. Any idea how to do it?
Thx
The correct syntax is:
i2.template f<T>();

clang error while compiling template [duplicate]

This question already has answers here:
Where and why do I have to put the "template" and "typename" keywords?
(8 answers)
Closed 5 years ago.
I am trying to touch C++17 features and I have selected clang.
Here is simplified example of my code that could not be compiled via clang:
#include <iostream>
#include <limits>
template<
typename T,
template<typename T_> typename Final>
class Base
{
public:
decltype(auto) Foo() const noexcept
{
using TFinal = Final<T>;
auto& _this = static_cast<const TFinal&>(*this);
return _this.Bar<true>();
}
};
template<typename T>
class Derived :
public Base<T, ::Derived>
{
public:
template<bool min>
T Bar() const noexcept
{
return min ?
std::numeric_limits<T>::lowest() :
std::numeric_limits<T>::max();
}
};
int main()
{
Derived<int> instance;
auto result = instance.Foo();
std::cout << result << std::endl;
return 0;
}
It fails here:
return _this.Bar<true>();
and error message is:
main.cpp:14:32: error: expected expression
return _this.Bar<true>();
^
main.cpp:35:10: error: variable has incomplete type 'void'
auto result = instance.Foo();
^
Here is how I am compiling it:
clang++-5.0 main.cpp -std=c++17
Some additional info. Visual Studio 17 with latest language version can eat this. When bar function is not template, everything is ok...
Any suggestions what is wrong here?
Should be
return _this.template Bar<true>();
In your case _this has dependent type. To refer to its member templates you have to use the keyword template explicitly.
Where and why do I have to put the "template" and "typename" keywords?

Error when calling an Integral template member function with g++ and clang++ [duplicate]

This question already has answers here:
Where and why do I have to put the "template" and "typename" keywords?
(8 answers)
Closed 7 years ago.
I'm currently stuck on a compilation error, which I can't really identify...
Here's a minimal working example:
#include <iostream>
template <typename T, int R>
class a_type
{
public:
template <int N>
double segment()
{
return 42;
}
};
template <int M>
double func()
{
a_type<double, M> a;
return a.segment<1>();
}
int main(int argc, char *argv[])
{
std::cout << func<10>() << std::endl;
return 0;
}
The error message from GCC reads:
g++ main.cpp -o main
main.cpp: In function 'double func()':
main.cpp:18:26: error: expected primary-expression before ')' token
return a.segment<1>();
^
main.cpp: In instantiation of 'double func() [with int M = 10]':
main.cpp:23:28: required from here
main.cpp:18:22: error: invalid operands of types '<unresolved overloaded function type>' and 'int' to binary 'operator<'
return a.segment<1>();
^
Clang also says something similar:
clang++ main.cpp -o main
main.cpp:18:26: error: expected expression
return a.segment<1>();
^
So based on GCC's error message, 'a.segment' is a member function call missing the parentheses, which obviously gets rejected. But that does not make sense at all, since I don't see any reason for treating that expression as such.
Moreover, if I change M to any integral number on line 17, like so:
#include <iostream>
template <typename T, int R>
class a_type
{
public:
template <int N>
double segment()
{
return 42;
}
};
template <int M>
double func()
{
a_type<double, 58> a;
return a.segment<1>();
}
int main(int argc, char *argv[])
{
std::cout << func<10>() << std::endl;
return 0;
}
then the code compiles and produces the expected result.
I would be very happy if somebody could enlighten me and show me what I am missing here.
The compiler doesn't know that a.segment is a template (it might depend on the value of M). So you have to tell it:
return a.template segment<1>();
In your second example it knows everything about the type of a, and so there is no problem.
The compiler tells you that it has problems with
a_type<double, M> a;
return a.segment<1>();
because it cannot tell what members a can have, as it is a template (that might be specialized for some values of M).
main.cpp:18:22: error: invalid operands of types '<unresolved overloaded function type>' and 'int' to binary 'operator<'
return a.segment<1>();
^
If segment is a template, it would be treated as segment<1>. If segment is a member variable of a, it should be compiled as a.segment < 1. How is the compiler to know?
You can fix this by using
return a.template segment<1>();

Address of templated member function [duplicate]

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.
In the example below, how do I find the address of the member function f
template<typename HANDLER>
void serialize(HANDLER &h) {
// Compiler error (gcc 4.8.1)
// test.cxx: In function ‘void serialize(HANDLER&)’:
// test.cxx:9:26: error: expected primary-expression before ‘int’
// auto x = &HANDLER::f<int>;
// ^
// test.cxx:9:26: error: expected ‘,’ or ‘;’ before ‘int’
auto x = &HANDLER::f<int>;
}
struct HandlerA {
template<typename T> void f() { }
};
struct HandlerB {
template<typename T> void f() { }
};
struct HandlerC {
template<typename T> void f() { }
};
int main() {
HandlerA a;
HandlerB b;
HandlerC c;
a.f<int>();
b.f<int>();
c.f<int>();
serialize(a);
serialize(b);
serialize(c);
}
You need to tell the compiler that f is a template so that it can parse the function correctly:
auto x = &HANDLER::template f<int>;
Casey is correct.
A template, before instantiation has no address. as the template is used (instantiated) with specific parameters, a unique function in memory is created.
You can use/create a real function with any type: int, char, float, double, classXYZ... there's no limit to how many pointers to that function there could be.