template error - cannot be a template definition - c++

I have created a simple LinkedList class using templates in C++
Basically I can create an instance of my list like this
LinkedList<int> myList = LinkedList<int>();
Now I would like to add a method to my LinkedList and provide a callback function so that function can call back to my code to perform an action.
I tried to create the following
template< typename T>
typedef bool(*LinkedList_SortCallBack2)(T);
But I receive a compiler error
error C2998: 'bool (_cdecl *_cdecl LinkedList_SortCallBack2)(T)' : cannot be a template definition
as a work around I have used void * but is there a way to do what I want? so my call back is like this
bool cb(int NewValue, int ExistingValue)
{
}
instead of
typedef bool (*LinkedList_SortCallBack)(void *value1, void* value2);
bool cb(void* NewValue, void* ExistingValue)
{
int a, b;
a = *(int *)NewValue;
b = *(int*)ExistingValue;
if (a < b)
return true;
else
return false;
}

Typedefs cannot be templates.
In C++11, use aliases
template <typename T>
using callback = void (*)(T);
In C++03, put it inside a structure
template <typename T>
struct SortCallback {
typedef void (*)(T) type;
};
typename SortCallback<int>::type callback;

Related

C++ name lookup inconsistency for template/overloaded functions

I'm building a minimal binary parser/serializer for one of my projects and I got this error that seems inconsistent at first. I have two top functions I want to expose T parse<T>(bytes) and bytevec serialize<T>(T const&) and from these two templated functions I delegate the serialization to overloaded functions based on the specific type provided. The problem is that the parsing side works fine, but the serialization side doesn't compile because it cannot see the overloaded function if it is defined after the top serialize function.
using bytevec = std::vector<uint8_t>;
using bytes = std::span<const uint8_t>;
template <typename T>
bytevec serialize(T const& data) {
bytevec b{};
serialize(data, b); // error: no matching function for call to 'serialize(const int&, bytevec&)
return b;
}
void serialize(int data, bytevec& b) {
b.push_back(0xff);
b.push_back(0xaa);
}
template <typename T>
struct tag {};
template <typename T>
T parse(bytes b) {
return parse(b, tag<T>{}); // fine
}
int parse(bytes b, tag<int>) { return b[1]; }
void test() {
static std::array<uint8_t, 2> data{0xff, 0xaa};
auto res1 = parse<int>(std::span(data));
auto res2 = serialize(res1);
}
Link to compiler explorer
Why is it ok for the top parse function to call an overloaded function defined later (int parse(bytes, tag<int>) and for the serialize function the overloaded function needs to be defined before in order to compile?
Thank you
ADL doesn't work for built-in types such as int.
For
template <typename T>
bytevec serialize(T const& data) {
std::vector<uint8_t> b{};
serialize(data, b);
return b;
}
With T=int
serialize(data, b); uses previous declaration, and can be looked-up in same namespace than std::vector<uint8_t> (so std). But no previous declarations and no std::serialize.
For
template <typename T>
T parse(bytes b) {
return parse(b, tag<T>{});
}
with T=int
parse(b, tag<int>{}) uses previous declaration, and can be looked-up in same namespace than tag<int> (so the global one) and std::span<const uint8_t> (so std). No previous declaration nor std::parse, but ::parse(int, tag<int>{}) exist.

Typedef and parameter pack expansion issues when working around partial template specialization of a function

I apologize ahead of time for the verbosity of the code.
I have been writing a small Lua bindings generator in C++ using TMP and I have encountered a need for partial template specialization of a function that I don't think can be resolved with a function overload. For clarity, I have omitted the actual Lua code.
EDIT: I understand that functions cannot be partially specialized.
Here is the code I want to write:
template<typename _Result, class _Class, typename ..._Args>
class LuaMethodRegistrar
{
public:
typedef _Result (_Class::*Func)(_Args...);
using _This = LuaMethodRegistrar<_Result, _Class, _Args...>;
enum { N_ARGS = std::tuple_size<std::tuple<_Args...>>::value };
public:
template <Func _Func>
static typename NamedRegistrar::RegisterFunc GetWrapper()
{
return Register<_Func>;
}
private:
template <Func _Func>
static bool Register(lua_State* L, char const* className, char const* methodName)
{
// register _This::LuaCallWrapper<_Result, _Func>
return true;
}
template<Func _Func>
static _Result MethodWrapper(void* object, _Args... args)
{
return (static_cast<_Class*>(object)->*_Func)(args...);
}
/////////////////// Key functions are down here ///////////////////
template <typename _Result, Func _Func>
static int LuaCallWrapper(lua_State* L)
{
// grab obj
int nArgs = N_ARGS;
return LuaReturn(L, MethodWrapper<_Func>(obj, LuaExtract<_Args>(L, nArgs)...)); // this line works fine here
}
template <Func _Func>
static int LuaCallWrapper<void, _Func>(lua_State* L)
{
// grab obj
MethodWrapper<_Func>(obj, LuaExtract<_Args>(L, nArgs)...));
return 0;
}
};
The Problems
Depending on the function that the client is trying to register, _Result could be void, which would result in an "invalid use of void expression" error when passing the result of LuaExtract (shown later) as the 2nd to 2+Nth arguments to MethodWrapper.
I cannot overload LuaWrapper because Lua expects a function pointer of type: int(*)(lua_State*).
My Attempted Solution:
I decided to make a new struct that I can partially specialize.
////////////////// Forward declared above but defined below LuaMethodRegistrar ///////////////////
template <typename _Result, typename _Class, typename ..._Args>
struct LuaCallWrapper
{
using Registrar = LuaMethodRegistrar<_Result, _Class, _Args...>;
enum { N_ARGS = std::tuple_size<std::tuple<_Args...>>::value };
template<_Result(_Class::*_Func)(_Args...)>
static int Call(lua_State* L)
{
// I can't use Registrar here because it gives me the "does not name a type error"
// Yet, when I use the full type, it finds it.
int nArgs = N_ARGS;
return LuaReturn(L, LuaMethodRegistrar<_Result, _Class, _Args...>::MethodWrapper<_Func>(obj, LuaExtract<_Args>(L, nArgs)...));
}
};
template <typename _Class, typename ..._Args>
struct LuaCallWrapper<void, _Class, _Args...>
{
using Registrar = LuaMethodRegistrar<void, _Class, _Args...>;
enum { N_ARGS = std::tuple_size<std::tuple<_Args...>>::value };
template<void(_Class::*_Func)(_Args...)>
static int Call(lua_State* L)
{
int nArgs = N_ARGS;
LuaMethodRegistrar<void, _Class, _Args...>::MethodWrapper<_Func>(obj, LuaExtract<_Args>(L, nArgs)...);
return 0;
}
};
////////////////////// Back in LuaMethodRegistrar::Register //////////////
// register LuaCallWrapper<_Result, _Class, _Args...>::Call<_Func>
Oddities/Problems
Types aren't being resolved correctly. e.g Registrar and consequently Registrar::Func "don't name a type".
On the call sites that use parameter pack expansion on a function call, I am getting "parameter packs not expanded with '...' " even though they look identical to the ones that worked in my original code.
Compilers: Clang 3.7.0, GCC 4.8.1
LuaExtract (the expansion context):
template <typename T>
inline T LuaExtract(lua_State* L, int& argCount);
template <>
inline int LuaExtract<int>(lua_State* L, int& argCount)
{
// get result
return result;
}
It seems to me that either the compilers are just getting bogged down with types, or, more likely, I am missing something. Thanks for your time.
EDIT: It looks like compiler can't resolve the types because LuaMethodRegistar<_Result, _Class, _Args...> and LuaCallWrapper<_Result, _Class, _Args...> depend on each other. How do I break that dependency?
It turns out, it only seemed like the types depended on each other because omitting the ::template in the call sites produces seemingly bizarre error messages.
This turned out to be a simple case of a bad compiler error message.
When I moved LuaCallWrapper out of the LuaMethodRegistrar, I forgot to add ::template to the member template function calls here:
return LuaReturn(L, LuaMethodRegistrar<_Result, _Class, _Args...>::MethodWrapper<_Func>(obj, LuaExtract<_Args>(L, nArgs)...));
here:
LuaMethodRegistrar<void, _Class, _Args...>::MethodWrapper<_Func>(obj, LuaExtract<_Args>(L, nArgs)...);
return 0;
and once inside the LuaMethodRegistrar itself.
Template member function calls that don't use ::template are treated as an "<unresolved overloaded function type>"
This lead to the compiler trying to evaluate things like this: LuaExtract<_Args>(L, nArgs)... on their own, making it complain about template parameter packs not expanded with "...", which makes sense.
The other type errors were fixed by these changes.

c++11 template argument ,wrong partial specialitzation from base definition

i am trying to implement a generic queue fifo, but i cannot make any progress in trying to select the correct specialization class from the one defined as a base template class.
Here is the code:
This code described first, a linked list implementation , so the class Node and the a enum class is defined to described the types of queue that is going to be used (linked list or fixed array), the first part (Node and GenericQueueType) work well, in the main function is defined first to do some test.
Then the wrapper function that going to be used as a wrapper class is not selecting the partial specialization defined for use the linked list.
#include <iostream>
#include <string>
//The node definition used for the linked list
template<typename ValueType>
struct Node_
{
Node_(): NodePtr(nullptr)
{}
Node_(const ValueType & aValue): _Value( aValue )
,NodePtr(nullptr)
{
}
ValueType _Value;
Node_ * NodePtr;
};
//====================
enum class EQueueType
{
EQueueType_Linked_List,
EQueueType_Fixed_Queue
};
//====================
template<EQueueType,class ... TypeValue>
struct GenericQueueType
{
};
template<class TypeValue>
struct GenericQueueType<EQueueType::EQueueType_Linked_List, TypeValue>
{
GenericQueueType():TopPtr(nullptr)
,BackPtr(nullptr)
{}
void insertValueInQueue(const TypeValue & aValue)
{
Node_<TypeValue > * aPtr=BackPtr;
BackPtr=new Node_<TypeValue>(aValue );
if(TopPtr==nullptr)
{
TopPtr=BackPtr;
}
else
{
BackPtr->NodePtr=aPtr;
}
}
void getValueFromQueue(TypeValue & aValue)
{
//aErrorcode=ERROR_PROCESS;
if (TopPtr!=nullptr)
{
Node_<TypeValue > * aPtr= TopPtr;
aValue=aPtr->_Value;
aPtr->_Value ;
TopPtr=TopPtr->NodePtr;
delete TopPtr;
TopPtr=nullptr;
}
}
private:
static const int ERROR_PROCESS = -1;
static const int OK_ERROR_CODE = 0;
Node_ <TypeValue > * TopPtr;
Node_ <TypeValue > * BackPtr;
};
//base queue wrapper
template<typename QueueType, typename ... Element>
class QueueFIFO
{
};
template< template<typename ... > class QueueType,typename EQ_type,typename ... TypeElement >
class QueueFIFO<QueueType<EQ_type,TypeElement ...>,EQ_type,TypeElement ... >
{
using value_type = typename std::tuple<TypeElement...>;
static const int INITIAL_SIZE=0;
public:
QueueFIFO():_Size(INITIAL_SIZE)
{}
void enqueue(const value_type & aElement)
{
Queue.insertValueInQueue(aElement);
}
void dequeue( value_type & aElement)
{
Queue.getValueFromQueue(aElement);
}
int size(){}
private:
int _Size;
QueueType<EQ_type,TypeElement ...> Queue;
};
int main()
{
float aElement=14;
GenericQueueType<EQueueType::EQueueType_Linked_List,float> aLinkedList;
aLinkedList.insertValueInQueue(aElement);
QueueFIFO<GenericQueueType<EQueueType::EQueueType_Linked_List,float>,float> _Queue;
_Queue.enqueue(aElement);
return 0;
}
Here is the compiler outs:
error: 'class QueueFIFO<GenericQueueType<(EQueueType)0, float>, float>' has no member named 'enqueue'
_Queue.enqueue(aElement);
^
I have been reading this from the standart:
In a type name that refers to a class template specialization, (e.g.,
A) the argument list shall match the template parameter
list of the primary template. The template arguments of a
specialization are deduced from the arguments of the primary template.
14.5.5.1
But still i cannot see the error.
Thx in advance!
The problem is somewhere in the template-template argument not actually creating a specialization. This is more clear if you declare the non-specialized version with just a ; instead of an empty definition.
The short answer is to not use template-template arguments; your code as written does not require them (or, in fact, any specialization at all of that template), and it is unlikely that you will ever see a case that needs them (in this case, it actually harms by eliminating possibly useful cases).
enqueue defined in your partial specialization of QueueFIFO takes a const & value_type where value_type is std::tuple. You are trying to call it with aElement which is a float, while you should be passing it a std::tuple<float>. Try passing std::make_tuple(aElement) to enqueue.
Also, as T.C. pointed out in the comments, the places you are using typename EQ_type and passing in an enum value of type EQueueType are erroneous - an enum value will not match a template type argument. You will have to use non-type arguments for that, as you have done in the definition of GenericQueueType.

Getting "illegal use of explicit template arguments" when doing a pointer partial specialization for a class method

Hello I'm having problems with partial specialization. What I want to do is have a class that has a template member function that will interpret a given value to one specified by the user. For instance the class name is Value and here is a snippet of what I want to do:
int *ptr1 = new int;
*ptr1 = 10;
Value val1 = ptr1;
int *ptr2 = val1.getValue<int*>();
Value val2 = 1;
int testVal = val2.getValue<int>();
Here is how I implemented such class:
struct Value {
Value(void *p) : val1(p){}
Value(int i) : val2(i){}
template<typename T>
T getValue();
void *val1;
int val2;
};
template<typename T>
T* Value::getValue<T*>() {
return reinterpret_cast<T*>(val1);
}
template<>
int Value::getValue<int>() {
return val2;
}
When I compile I'm getting the following error:
error C2768: 'Value::getValue' : illegal use of explicit template
arguments
Basically its complaining about the pointer template part of the code:
template<typename T>
T* Value::getValue<T*>() {
return reinterpret_cast<T*>(val1);
}
I know this problem can be implemented with a simple union, But this code is a stripped down version of a bigger code.
Does someone know what the problem could be? What I would like to do is separate one code for when using pointers and other for when not using pointers . I'm really stuck and I always investigate instead of asking, but I haven't found any good info about it.
Function templates cannot be partially specialised, but most of the time, you can use the delegate-to-class trick. In you example it would be like this:
struct Value {
template<typename T>
T getValue() {
return Impl_getValue<T>::call(*this);
}
};
template <typename T>
struct Impl_getValue
{
static T call(Value &v) {
//primary template implementation
}
};
template <typename T>
struct Impl_getValue<T*>
{
static T* call(Value &v) {
return reinterpret_cast<T*>(v.val1);
}
};

Deduction template argument C++

Please, consider the code below:
template<typename T>
bool function1(T some_var) { return true; }
template <typename T>
bool (*function2())(T) {
return function1<T>;
}
void function3( bool(*input_function)(char) ) {}
If I call
function3(function2<char>());
it is ok. But if I call
function3(function2());
compiler gives the error that it is not able to deduction the argument for template.
Could you, please, advise (give an idea) how to rewrite function1 and/or function2 (may be, fundamentally to rewrite using classes) to make it ok?
* Added *
I am trying to do something simple like lambda expressions in Boost.LambdaLib (may be, I am on a wrong way):
sort(some_vector.begin(), some_vector.end(), _1 < _2)
I did this:
template<typename T>
bool my_func_greater (const T& a, const T& b) {
return a > b;
}
template<typename T>
bool my_func_lesser (const T& a, const T& b) {
return b > a;
}
class my_comparing {
public:
int value;
my_comparing(int value) : value(value) {}
template <typename T>
bool (*operator<(const my_comparing& another) const)(const T&, const T&) {
if (this->value == 1 && another.value == 2) {
return my_func_greater<T>;
} else {
return my_func_greater<T>;
}
}
};
const my_comparing& m_1 = my_comparing(1);
const my_comparing& m_2 = my_comparing(2);
It works:
sort(a, a + 5, m_1.operator< <int>(m_2));
But I want that it doesn't require template argument as in LambdaLib.
Deduction from return type is not possible. So function2 can't be deduced from what return type you expect.
It is however possible to deduce cast operator. So you can replace function2 with a helper structure like: Unfortunately there is no standard syntax for declaring cast operator to function pointer without typedef and type deduction won't work through typedef. Following definition works in some compilers (works in G++ 4.5, does not work in VC++ 9):
struct function2 {
template <typename T>
(*operator bool())(T) {
return function1<T>;
}
};
(see also C++ Conversion operator for converting to function pointer).
The call should than still look the same.
Note: C++11 introduces alternative typedef syntax which can be templated. It would be like:
struct function2 {
template <typename T>
using ftype = bool(*)(T);
template <typename T>
operator ftype<T>() {
return function1<T>;
}
};
but I have neither G++ 4.7 nor VC++ 10 at hand, so I can't test whether it actually works.
Ad Added:
The trick in Boost.Lambda is that it does not return functions, but functors. And functors can be class templates. So you'd have:
template<typename T>
bool function1(T some_var) { return true; }
class function2 {
template <typename T>
bool operator()(T t) {
function1<T>;
}
};
template <typename F>
void function3( F input_function ) { ... input_function(something) ... }
Now you can write:
function3(function2);
and it's going to resolve the template inside function3. All STL takes functors as templates, so that's going to work with all STL.
However if don't want to have function3 as a template, there is still a way. Unlike function pointer, the std::function (C++11 only, use boost::function for older compilers) template can be constructed from any functor (which includes plain function pointers). So given the above, you can write:
void function3(std::function<bool ()(char)> input_function) { ... input_function(something) ... }
and now you can still call:
function3(function2());
The point is that std::function has a template constructor that internally generates a template wrapper and stores a pointer to it's method, which is than callable without further templates.
Compiler don't use context of expression to deduce its template parameters. For compiler, function3(function2()); looks as
auto tmp = function2();
function3(tmp);
And it don't know what function2 template parameter is.
After your edit, I think what you want to do can be done simpler. See the following type:
struct Cmp {
bool const reverse;
Cmp(bool reverse) : reverse(reverse) {}
template <typename T> bool operator()(T a, T b) {
return reverse != (a < b);
}
};
Now, in your operator< you return an untyped Cmp instance depending on the order of your arguments, i.e. m_2 < m_1 would return Cmp(true) and m_1 < m_2 would return Cmp(false).
Since there is a templated operator() in place, the compiler will deduce the right function inside sort, not at your call to sort.
I am not sure if this help you and I am not an expert on this. I have been watching this post since yesterday and I want to participate in this.
The template cannot deduce it's type because the compiler does not know what type you are expecting to return. Following is a simple example which is similar to your function2().
template<typename T>
T foo() {
T t;
return t;
};
call this function
foo(); // no type specified. T cannot be deduced.
Is it possible to move the template declaration to the class level as follows:
template<typename T>
bool my_func_greater (const T& a, const T& b) {
return a > b;
}
template<typename T>
bool my_func_lesser (const T& a, const T& b) {
return b > a;
}
template <typename T>
class my_comparing {
public:
int value;
my_comparing(int value) : value(value) {}
bool (*operator<(const my_comparing& another) const)(const T&, const T&) {
if (this->value == 1 && another.value == 2) {
return my_func_greater<T>;
} else {
return my_func_greater<T>;
}
}
};
and declare m_1 and m_2 as below:
const my_comparing<int>& m_1 = my_comparing<int>(1);
const my_comparing<int>& m_2 = my_comparing<int>(2);
Now you can compare as follows:
if( m_1 < m_2 )
cout << "m_1 is less than m_2" << endl;
else
cout << "m_1 is greater than m_2" << endl;
I know this is simple and everyone knows this. As nobody posted this, I want to give a try.