Template parameter to a template - ambiguous symbol - c++

I found this example of another template passed as parameter to a template:
template<template<typename T> class AllocatePolicy>
struct Pool {
void allocate(size_t n) {
int *p = AllocatePolicy<int>::allocate(n);
}
};
template<typename T>
struct allocator { static T * allocate(size_t n) { return 0; } };
int main()
{
// pass the template "allocator" as argument.
Pool<allocator> test;
return 0;
}
This seems perfectly reasonable to me but MSVC2012 compiler is complaining that "allocator: ambiguous symbol"
Is this a compiler-problem or is there something wrong with this code?

You most likely have an evil:
using namespace std;
Somewhere in your code, which makes your class template allocator clash with the std::allocator Standard allocator.
For instance, this code does not compile unless you comment the line containing the using directive:
#include <memory>
// Try commenting this!
using namespace std;
template<template<typename T> class AllocatePolicy>
struct Pool {
void allocate(std::size_t n) {
int *p = AllocatePolicy<int>::allocate(n);
}
};
template<typename T>
struct allocator { static T * allocate(std::size_t n) { return 0; } };
int main()
{
Pool<allocator> test;
}

Related

How do I format my function to call a templated class?

I'm sure there is a very easy answer, but I can't figure it out. I have written a templated class, but I want to pass that class by reference in a class function that isn't templated. Heres what I have. I get a bunch of errors. All I need to do is figure how to format the way to insert templated class into function, but I'm at a lost. Thank you and sorry if the code doesn't really help you out.
#include <iostream>
using namespace std;
template <typename T>
class Foo {
public:
Foo();
insert(const T& Item)
//And other function, just examples
};
class noFoo(){
void test(Foo <T>& foo);
int i;
int j;
int k
};
template <typename T>
void noFoo::test(Food <T>& foo)}
cout << "hi";
}
int main() {
Foo<char> wr;
test(wr);
return 0;
}
Make test a function template. I also corrected loads of syntax errors for you (class noFoo()?), removed unnecessary code, and ran clang-format for indentation.
#include <iostream>
template <typename T>
class Foo {};
class noFoo
{
public:
template <typename T>
void test(Foo<T> &);
};
template <typename T>
void noFoo::test(Foo<T> &)
{
std::cout << "hi\n";
}
int main()
{
Foo<char> wr;
noFoo{}.test(wr);
}
Since your question is tagged d, here the same code in D.
import std.stdio;
class Foo(T) {};
class noFoo
{
public:
void test(T)(Foo!(T))
{
writeln("hi");
}
};
void main()
{
auto wr = new Foo!char;
(new noFoo).test(wr);
}

Nested template C++

I have a template class of the form:
template<typename ContainerType>
class ConfIntParamStat {
public:
typedef typename ContainerType::Type Type;
...
private:
void sample(int iteration) {...}
}
I would like to create a specific version of the function sample for the case when ContainerType is a Vector. Where Vector itself is a template class, but I do not know which type of values this Vector holds.
My intuition was to create this in the header file:
template<typename Type>
ConfIntParamStat<Vector<Type> >::sample(int iteration) {
...
}
But it does not compile, and the error from clang is:
error: nested name specifier 'ConfIntParamStat<Vector<Type> >::' for declaration does not refer into a class, class template or class template partial specialization
Is it possible using another syntax ?
If you didnt want to specialize the template and were looking for a member only specialization try the following
#include <iostream>
#include <vector>
using namespace std;
template <typename ContainerType>
class Something {
public:
void do_something(int);
template <typename Which>
struct do_something_implementation {
void operator()() {
cout << "general implementation" << endl;
}
};
template <typename Which>
struct do_something_implementation<vector<Which>> {
void operator()() {
cout << "specialized implementation for vectors" << endl;
}
};
};
template <typename ContainerType>
void Something<ContainerType>::do_something(int) {
do_something_implementation<ContainerType>{}();
}
int main() {
Something<double> something;
something.do_something(1);
return 0;
}
If your intent is to specialize a function, I would just overload the function like so
#include <iostream>
#include <vector>
using namespace std;
template <typename ContainerType>
class Something {
public:
void do_something(int);
template <typename Type>
void do_something(const vector<Type>&);
};
template <typename ContainerType>
void Something<ContainerType>::do_something(int) {
cout << "Called the general method for do_something" << endl;
}
template <typename ContainerType>
template <typename Type>
void Something<ContainerType>::do_something(const vector<Type>&) {
cout << "Called the specialised method" << endl;
}
int main() {
vector<int> vec{1, 2, 3};
Something<double> something;
something.do_something(1);
something.do_something(vec);
return 0;
}
This is mostly why full/explicit function template specializations are not required. Overloading allows for almost the same effects!
Note This is a great article related to your question! http://www.gotw.ca/publications/mill17.htm
You could make use of the overloading mechanism and tag dispatch:
#include <vector>
template <class T>
struct Tag { };
template<typename ContainerType>
class ConfIntParamStat {
public:
typedef typename ContainerType::value_type Type;
//...
// private:
void sample(int iteration) {
sample_impl(Tag<ContainerType>(), iteration);
}
template <class T>
void sample_impl(Tag<std::vector<T> >, int iteration) {
//if vector
}
template <class T>
void sample_impl(Tag<T>, int iteration) {
//if not a vector
}
};
int main() {
ConfIntParamStat<std::vector<int> > cips;
cips.sample(1);
}
As skypjack mentioned this approach has a little draw when using const. If you are not using c++11 (I suspect you dont because you use > > syntax for nested templates) you could workaround this as follows:
#include <iostream>
#include <vector>
template <class T>
struct Tag { };
template <class T>
struct Decay {
typedef T Type;
};
template <class T>
struct Decay<const T> {
typedef T Type;
};
template<typename ContainerType>
class ConfIntParamStat {
public:
typedef typename ContainerType::value_type Type;
//...
// private:
void sample(int iteration) {
sample_impl(Tag<typename Decay<ContainerType>::Type>(), iteration);
}
template <class T>
void sample_impl(Tag<std::vector<T> >, int iteration) {
std::cout << "vector specialization" << std::endl;
}
template <class T>
void sample_impl(Tag<T>, int iteration) {
std::cout << "general" << std::endl;
}
};
int main() {
ConfIntParamStat<const std::vector<int> > cips;
cips.sample(1);
}
Another way to approach this is composition.
The act of adding a sample can be thought of as a component of the implementation of the class. If we remove the implementation of adding a sample into this template class, we can then partially specialise only this discrete component.
For example:
#include <vector>
//
// default implementation of the sample component
//
template<class Outer>
struct implements_sample
{
using sample_implementation = implements_sample;
// implements one function
void sample(int iteration) {
// default actions
auto self = static_cast<Outer*>(this);
// do something with self
// e.g. self->_samples.insert(self->_samples.end(), iteration);
}
};
// refactor the container to be composed of component(s)
template<typename ContainerType>
class ConfIntParamStat
: private implements_sample<ConfIntParamStat<ContainerType>>
{
using this_class = ConfIntParamStat<ContainerType>;
public:
// I have added a public interface
void activate_sample(int i) { sample(i); }
// here we give the components rights over this class
private:
friend implements_sample<this_class>;
using this_class::sample_implementation::sample;
ContainerType _samples;
};
//
// now specialise the sample function component for std::vector
//
template<class T, class A>
struct implements_sample<ConfIntParamStat<std::vector<T, A>>>
{
using sample_implementation = implements_sample;
void sample(int iteration) {
auto self = static_cast<ConfIntParamStat<std::vector<T, A>>*>(this);
// do something with self
self->_samples.push_back(iteration);
}
};
int main()
{
ConfIntParamStat< std::vector<int> > cip;
cip.activate_sample(1);
cip.activate_sample(2);
}

Templated class member VS Nested class forward declaration

Good evening everyone!
I'm stuck with an itchy problem. Say I have the following code :
#include <iostream>
template <class T>
struct MyTemplate {
int _array[sizeof (T)];
} ;
struct MyStruct {
struct MyNestedStruct {
int foo;
} ;
MyTemplate<MyNestedStruct> _nested;
} ;
int main(int, char **) {
return 0;
}
This example snippet compiles fine. What I would like to do is lift the definition of MyNestedStruct out of MyStruct :
#include <iostream>
template <class T>
struct MyTemplate {
int _array[sizeof (T)];
} ;
struct MyStruct {
struct MyNestedStruct;
MyTemplate<MyNestedStruct> _nested;
} ;
struct MyStruct::MyNestedStruct {
int foo;
} ;
int main(int, char **) {
return 0;
}
Of course this one doesn't compile since I'm requesting the size of a partially declared type (error: invalid application of ‘sizeof’ to incomplete type ‘MyStruct::MyNestedStruct’).
My real use case does need sizeof, but will also use several MyNestedClass-like template parameters in that fashion, each fully declared with constructors and the like. For this reason I don't want MyClass to get bloated. Can I do anything about it, or will I have to resort to an external scope (namespace) to put my "inner" classes in ?
Unless...
struct MyStruct {
#include "MyNestedStruct.h" // Dirty preprocessor to the rescue !
MyTemplate<MyNestedStruct> _nested;
} ;
Ugh.
Essentially we need to defer template instantiation of MyTemplate since that's the one that requires T to be complete. The trick I can see to do that here is to templatize MyStruct.
template <typename T>
struct MyTemplate {
int _array[sizeof(T)];
};
template <typename Dummy = void>
struct MyStruct {
struct MyNestedStruct;
MyTemplate<MyNestedStruct> _nested;
};
template <typename Dummy>
struct MyStruct<Dummy>::MyNestedStruct {
int foo;
};
int main() {}
Now we've deferred the instantiation of MyStruct, but we need to use MyStruct<> instead. If that's unsatisfactory, then just provide a type alias.
#include <iostream>
template <typename T>
struct MyTemplate {
int _array[sizeof(T)];
};
template <typename Dummy = void>
struct MyStructImpl {
struct MyNestedStruct;
MyTemplate<MyNestedStruct> _nested;
};
template <typename Dummy>
struct MyStructImpl<Dummy>::MyNestedStruct {
int foo;
};
using MyStruct = MyStructImpl<>;
int main() {
MyStruct s;
std::cout << sizeof(s._nested._array) << std::endl;
}
Prints 16.
Note: you could also to hide MyStructImpl in a detail namespace or something similar.

Interdependent class templates design?

Consider the following design :
template <class SecondType>
struct First
{
SecondType* _ptr;
};
template <class FirstType>
struct Second
{
FirstType* _ptr;
};
where the First type has a pointer to a Second type and vice-versa. The problem is that I cannot declare this because they are interdependent and I should declare First<Second<First<Second...>>>.
How to solve this problem ?
Maybe a work-around with something that looks like CRTP but even crazier:
#include <iostream>
template <class SecondType>
struct FirstBase
{
SecondType* _ptr;
};
template <class FirstType>
struct SecondBase
{
FirstType* _ptr;
};
struct FirstDerived
: public FirstBase<SecondBase<FirstDerived>>
{
};
struct SecondDerived
: public SecondBase<FirstBase<SecondDerived>>
{
};
int main()
{
FirstBase<SecondDerived> x;
SecondBase<FirstDerived> y;
return 0;
}
If someone has a more elegant way to do this, I would be happy to see it.
Not sure what you are trying to achieve but the following compiles fine.
template <class T> struct First { T* _ptr; };
template <class T> struct Second { T* _ptr; };
int main(){
First<Second<First<Second<void>>>> a; // or
First<Second<First<Second<nullptr_t>>>> b;
return 0;
}
Note I replaced FirstType, SecondType altogether cos it does not matter. T would be replaced by whatever you pass and this will happen when the template is being specialized before compilation.
Here is another possibly more elegant solution which doesn't require void at all. I don't know if the inheritance is acceptable to you but I think it works well.
#include<vector>
#include<algorithm>
#include<iostream>
using namespace std;
struct Base {
//make all functions virtual
};
template <class SecondType>
struct First: public Base
{
SecondType* _ptr;
First(SecondType * st) {
_ptr = st;
}
First() {
}
};
template <class FirstType>
struct Second: public Base
{
FirstType* _ptr;
Second(FirstType * ft) {
_ptr = ft;
}
Second() {
}
};
int main() {
First<Base> f;
Second<Base> s;
f._ptr = &s;
s._ptr = &f;
cout << s._ptr << endl;
}

ambiguous template overload for template parameter is a container

Please consider the following example:
#include <string>
#include <vector>
using std::string;
using std::vector;
template <typename T>
const T GetValue()
{
return T(); // some value
}
template <typename T>
const vector<T> GetValue()
{
return vector<T>(); // some vector of values
}
int main(int argc, char* argv[])
{
int i = GetValue<int>();
vector<int> = GetValue<vector<int>>();
return 0;
}
I have two template functions which are supposed to parse values from some storage depending on an given type. The first should do the job for simple data types, the second for vectors of simple data types only.
My problem is that the template matching is ambiguous since T may be vector<T>.
I wonder how to implement the overload/specialization for the vector types properly.
Any help would be greatly appreciated!
One simple way is to use an out-param, so that the template parameter can be deduced from the argument:
#include <vector>
using std::vector;
template <typename T>
void GetValue(T &t)
{
t = T(); // some value
}
template <typename T>
void GetValue(vector<T> &v)
{
v = vector<T>(); // some vector of values
}
int main(int argc, char* argv[])
{
int i;
GetValue(i);
vector<int> v;
GetValue(v);
return 0;
}
GetValue(v) isn't ambiguous, since the template argument deduction rules say that the second overload is the better match.
This isn't necessarily the interface/style you want, though, in which case you could use partial specialization instead of overloading. But that requires a class, since function templates cannot be partially specialized:
#include <vector>
using std::vector;
template <typename T>
struct Getter {
T get(void) {
return T(); // some value
}
};
template <typename T>
struct Getter<vector<T> > {
vector<T> get(void) {
return vector<T>(); // some vector of values
}
};
template <typename T>
T GetValue(void)
{
return Getter<T>().get();
}
int main(int argc, char* argv[])
{
int i = GetValue<int>();
vector<int> v = GetValue<vector<int> >();
return 0;
}
Both version ofGetValue differs by only return type, hence it is not overload.
I would suggest you to have just one GetValue and then implement two functions which differ by parameter type, as opposed to return type, and forward the call as:
namespace details
{
template <typename T>
T FillValue(T*)
{
//your code
}
template <typename T>
vector<T> FillValue(vector<T> *)
{
//your code
}
}
template <typename T>
T GetValue()
{
return details::FillValue((T*)0); //pass null pointer of type T*
}
The correct FillValue will be selected by the compiler based on the type of the argument passed to the function, which is T*. If T is vector<U> for some type U, then the second function will be selected, otherwise the first function will be selected.
You can move the partial specialization to a helper class:
#include <vector>
template <typename T>
class Creator {
public:
T operator()() const { return T(); }
};
template <typename T>
class Creator<std::vector<T> > {
public:
std::vector<T> operator()() const { return std::vector<T>(); }
};
template <typename T>
T GetValue() {
return Creator<T>()();
}
int main() {
int i = GetValue<int>();
std::vector<char> v = GetValue<std::vector<char> >();
}
Put the general method inside a class (naming as GetValue preferably) and declare that method as operator T(). Now specialize the class for vector<T>:
template <typename T>
struct GetValue
{
operator const T () const
{
std::cout<<"GetValue()\n";
return T(); // some value
}
};
template <typename T>
struct GetValue<vector<T> >
{
operator const vector<T> ()
{
std::cout<<"GetValue<vector<T>>()\n";
return vector<T>(); // some vector of values
}
};
Usage:
int i = GetValue<int>();
vector<int> v = GetValue<vector<int> >();
Demo