I try to forward declare concurrent_bounded_queue ;
class MyClass {
namespace tbb {
template<typename T> class cache_aligned_allocator;
template<class T, class A = cache_aligned_allocator> class concurrent_bounded_queue;
};
// I wish to maintain this syntax.
tbb::concurrent_bounded_queue<std::string>& concurrentBoundedQueue;
}
I get the following error :
error C3203: 'cache_aligned_allocator' : unspecialized class template can't be used as a template argument for template parameter 'A', expected a real type
error C2955: 'tbb::cache_aligned_allocator' : use of class template requires template argument list c:\projects\vitroxreport\src\Executor.h(21) : see declaration of 'tbb::cache_aligned_allocator'
May I know how I can avoid?
Thanks.
Allocator is a template, but second argument of the queue is concrete class. Try this:
class MyClass {
namespace tbb {
template<typename T> class cache_aligned_allocator;
template<class T, class A = cache_aligned_allocator<T> >
class concurrent_bounded_queue;
};
tbb::concurrent_bounded_queue<std::string>& concurrentBoundedQueue;
};
Related
I'm trying to experiment with CRTP but I am puzzled on why the following code does not compile.
template<template<class...> class CBase>
struct ComponentX : public CBase<ComponentX>
{
// This does NOT compile
};
template<template<class...> class CBase>
struct ComponentY : public CBase<int>
{
// This does compile
};
Do you know if there is some limitation for template template parameters in the case of CRTP?
A class template name stands for the "current specialization" (i.e. it is an injected class name) only after the opening { of the class template definition, inside its scope. Before that, it's a template name.
So CBase<ComponentX> is an attempt to pass a template as an argument to CBase, which expects a pack of types.
The fix is fairly simple:
template<template<class...> class CBase>
struct ComponentX : public CBase<ComponentX<CBase>> // Specify the arguments
{
// This should compile now
};
ComponentX<CBase> is the name of the specialization you wish to provide as a type argument.
I am trying to create a derived class that is using a nested class as a template argument for a parent class, but the compiler is unable to instanciate the template:
template<typename T>
class A {};
template<typename T>
class B : public A<typename B<T>::nested_class >
{
class nested_class : public std::pair<std::string, T>
{
// adds methods that use the T type
};
};
MSVC 2010 gives me 3 errors trying to compile this:
syntax error : missing ',' before identifier 'nested_class'
'nested_class' : undeclared identifier
'A' : use of class template requires template argument list
Moving the nested class out and making it separate solves the problem, but I want to understand why this doesn't compile.
I need to use a template class which is defined in another template class as parameter of another template as return value in template method. I know it sounds complicated, code below explains it better. Problem is that the code cannot be compiled, it ends with following error:
type/value mismatch at argument 2 in template parameter list for 'template<class T, template<class> class Policy> class Result'
expected a class template, got 'CDummy<T2>::Policy2'
but I'm pretty sure that given class fulfills needs. Problem is that the method, which uses it, is template too and so compiler does not know what exactly CDummy<T2>::Policy2 is. If the Policy2 would not be template, but regular class or if I could fill its argument, I would use typename which would tell the compiler not to worry about it, but how can this be done with template?
// I cannot change this interface - it's given by a library
template <class T, template <class> class Policy>
class Result : public Policy<T>
{
T data;
};
template <class T>
class Policy1
{
};
// I use this for allowing Policy2 to change behaviour according Dummy
// while it keeps template interface for class above
template <class Dummy>
class CDummy
{
public:
template <class T>
class Policy2 : public Policy1<T>
{
};
};
// Both variables are created ok
Result<int, Policy1 > var1;
Result<int, CDummy<float>::Policy2 > var2;
// This is ok, too
template <class T>
Result<T, Policy1 > calc1()
{
return Result<int, Policy1>();
}
// But this ends with the error:
// type/value mismatch at argument 2 in template parameter list for 'template<class T, template<class> class Policy> class Result'
// expected a class template, got 'CDummy<T2>::Policy2'
template <class T1, class T2>
Result<T1, CDummy<T2>::Policy2 > calc2() // <-- Here is the generated error
{
typedef typename DummyTypedef CDummy<T2>;
return Result<T1, DummyTypedef::Policy2>();
}
Notes:
I use gcc 4.7.3 32bit in GNU/Linux Ubuntu 13.04. 32 bit.
For various reasons, I cannot use C++11 standard (yet) and so I cannot use template typedefs
I believe that the name CDummy<T2>::Policy2 is a dependent name in that context and that you should use the template keyword to inform the compiler that it is indeed a template.
template <class T1, class T2>
Result<T1, CDummy<T2>::template Policy2 > calc2() // <-- Here is the generated error
// ^^^^^^^^
additionally the implementation of that same function seems to be wrong also. The order of typedefs is original name, new name, and CDummy<T2> is known to be a type (i.e. there is no need for the typename):
typedef CDummy<T2> DummyTypedef;
The return statement would then be:
return Result<T1, DummyTypedef::template Policy2>();
I am thinking about using curiously recurring template pattern for my application. However, I would like the classes to operate on the user defined types. I would like to understand if it is possible to create a structure similar to the one shown below:
template <class T_leaftype>
class BaseTrajectoryPoint {
};
template <class MyType>
class MyTrajectoryPoint: public BaseTrajectoryPoint<MyTrajectoryPoint> {
private:
MyType A;
};
The code above fails to compile with the following error:
type/value mismatch at argument 1 in template parameter list for ‘template class BaseTrajectoryPoint’
Are there any alternative ways of approaching the problem? I would like to use static polymorphism, but I would prefer to define all possible methods in the base class.
template <class T_leaftype>
class BaseTrajectoryPoint {
};
template <class MyType>
class MyTrajectoryPoint: public BaseTrajectoryPoint<MyTrajectoryPoint<MyType> > {
private:
MyType A;
};
MyTrajectoryPoint isn't a type, it's template; when you pass it as template parameter, it's seen as template<typename> class T>, not template<class T> - and the latter is what your base class is expecting. But MyTrajectoryPoint<MyType> names a type, so you can use it as template parameter of your base class.
Of course, you can change declaration of BaseTrajectoryPoint to template<template<class> class T_leaftype>, but then you would have to use class template as template parameter, never a complete type.
What our friend Griwes said is correct, although if you know that every class that will inherit BaseTrajectoryPoint is a template class, you can do the following:
template<template < class > class TLeaf> // << This means: It is expected a template class as parameter
class BaseTrajectoryPoint{
};
template <class MyType>
class MyTrajectoryPoint: public BaseTrajectoryPoint<MyTrajectoryPoint> >{
private:
MyType A;
};
Modern C++ Design gives the following example:
template <class T> struct EnsureNotNull
{
static void Check(T*& ptr)
{
if (!ptr) ptr = GetDefaultValue();
}
};
template
<
class T,
template <class> class CheckingPolicy = EnsureNotNull,
template <class> class ThreadingModel
>
class SmartPtr
: public CheckingPolicy<T>
, public ThreadingModel<SmartPtr>
{
...
T* operator->()
{
typename ThreadingModel<SmartPtr>::Lock guard(*this);
CheckingPolicy<T>::Check(pointee_);
return pointee_;
}
private:
T* pointee_;
};
I couldn't figure how ThreadingModel template would be constructed in a fashion that It could accept SmartPtr as parameter, in my mind some crazy recursion is going to happen. How can this be possible?
Edit:
I've tried Potatoswatter (sorry lol) comment:
template <class SmartPtr> struct SingleThreadingModel
{
class Lock
{
public:
Lock(SmartPtr&)
{
}
};
};
but it did'nt worked.
here is the error that gcc is giving me:
main.cpp:28:35: error: type/value mismatch at argument 1 in template parameter list for ‘template<class> class ThreadingModel’
main.cpp:28:35: error: expected a type, got ‘SmartPtr’
You are trying to pass SmartPtr as a template type argument to ThreadingModel. SmartPtr however is a template, not a concrete type, and the injected class-name is not available in the inheritance list.
Also note that you can't just use default arguments for template parameters in arbitrary positions (§14.1/11):
If a template-parameter has a default template-argument, all subsequent template-parameters shall have a default template-argument supplied.
Your code with those issues fixed:
template
<
class T,
template <class> class ThreadingModel,
template <class> class CheckingPolicy = EnsureNotNull
>
class SmartPtr
: public CheckingPolicy<T>
, public ThreadingModel<SmartPtr<T, ThreadingModel, CheckingPolicy> >
// ^ .... now passing a concrete class .... ^
{
T* operator->() {
// the following use of SmartPtr is fine as it is the injected class-name:
typename ThreadingModel<SmartPtr>::Lock guard(*this);
// ...
}
};
Note that while Modern C++ Design is an excellent book, it can't replace a good basic book on templates like Vandevoorde/Josuttis.
The recursion is OK because passing a specialization as a template parameter does not directly cause it to be instantiated.
(ThreadingModel<SmartPtr> in the base list is just shorthand for ThreadingModel< SmartPtr< T, CheckingPolicy, ThreadingModel > > which uses the "current specialization.")
I don't know what ThreadingModel is supposed to do, so I can't implement it, but it should have a declaration of the form
template< class Client > class MyThreading
and it cannot access anything inside Client outside of MyThreading member functions. If you use Client and Client depends on MyThreading, then infinite recursion does happen.