C++ template arguments in constructor - c++

Why doesn't this code compile?
template <class T>
class A
{
public:
A(T t) : t_(t) {}
private:
T t_;
};
int main()
{
A a(5.5);
// A<double> a(5.5); // that's what i don't want to do
}
I want template arguments to be implicit.
Like in this example:
template<class T>
T Foo(T t) { return t; }
// usage:
Foo(5.5);
UPDATE: named-constructor idiom isn't acceptable for me. I want to use this class for RAII.
The only way to do so is const A& a = A::MakeA(t), but it's ugly!

Since you have to name the type of a variable (C++03 can't infer the type of a variable), you can only do:
A<double> a(5.5); // that's what i don't want to do
The situation is a little easier when you needn't make a variable of the type, but want to pass it to some other function. In this case, you define an auxiliary "constructor function" (see std::make_pair):
template <class T>
A<T> make_a(T t) { return A<T>(t); }
and then use it like this:
another_function(make_a(1.1));
In C++0x, you will be able to do even
auto a(make_a(5.5));
to define your variable a.
However, inferring A's argument from its constructor is generally impossible, because you can't tell which specializations have the conversion constructor from a given type. Imagine there's a specialization
template <>
struct A<void>
{
A(double);
};

Related

Explicit instantiation of template class with templated member functions

With a class defined as follows:
template <typename T>
class A {
private:
T a;
public:
A(T& a) : a_(a) { }
template <typename D>
void Eval(D& arg)
{
// ...
}
};
template A<int>;
I want to explicitly instantiate one instance of the class, and I want this class to have one explicit instantiation of Eval. The intention here is to get a member function pointer that avoids ambiguity:
auto eval_ptr = &A<int>::Eval;
The ambiguity is not coming from anything to do with template instantiation of the class, it's caused by Eval also being a templated function.
&A<int>::Eval does not point to a function, it points to a template. And there is just no such type as a "pointer to a template".
If you want a pointer to A<int>::Eval, you need to specify D as well.
auto eval_ptr = &A<int>::Eval<int>; works just fine for example.
Addendum: Pointers-to-templates do exist in the grammatical sense, but there is no type an object can have to hold one of them. They must be immediately casted/decayed to a specific overload in order to be used, which doesn't come into play here since you want to store it in an auto.
For example: The following is fine because there's clearly only one "version" of Eval that can be meant:
void bar(void (A<int>::*arg)(int&)) {}
void foo() {
bar(&A<int>::Eval);
}
The very simple solution was specifying both template parameters:
template <typename T>
class A
{
private:
T a;
public:
A(T &a) : a_(a) {}
template <typename D>
void Eval(D &arg)
{
arg+=1;
}
};
int main()
{
auto p = &A<int>::Eval<int>;
}

Overload operator [] with a template [duplicate]

In C++, can you have a templated operator on a class? Like so:
class MyClass {
public:
template<class T>
T operator()() { /* return some T */ };
}
This actually seems to compile just fine, but the confusion comes in how one would use it:
MyClass c;
int i = c<int>(); // This doesn't work
int i = (int)c(); // Neither does this*
The fact that it compiles at all suggests to me that it's doable, I'm just at a loss for how to use it! Any suggestions, or is this method of use a non-starter?
You need to specify T.
int i = c.operator()<int>();
Unfortunately, you can't use the function call syntax directly in this case.
Edit: Oh, and you're missing public: at the beginning of the class definition.
You're basically right. It is legal to define templated operators, but they can't be called directly with explicit template arguments.
If you have this operator:
template <typename T>
T operator()();
as in your example, it can only be called like this:
int i = c.operator()<int>();
Of course, if the template argument could be deduced from the arguments, you could still call it the normal way:
template <typename T>
T operator()(T value);
c(42); // would call operator()<int>
An alternative could be to make the argument a reference, and store the output there, instead of returning it:
template <typename T>
void operator()(T& value);
So instead of this:
int r = c.operator()<int>();
you could do
int r;
c(r);
Or perhaps you should just define a simple get<T>() function instead of using the operator.
Aren't you thinking of
class Foo {
public:
template<typename T>
operator T() const { return T(42); }
};
Foo foo;
int i = (int) foo; // less evil: static_cast<int>(foo);
live example. This proves you do not need to specify the template argument, despite the claim in the accepted answer.

Pass functor to constructor

I have a class that basically needs to store a functor given in the constructor, similar to this:
template <class T>
class Foo {
private:
T func;
public:
Foo(T f) : func(f) { }
}
However, to create a new instance of the Foo class, the I can't seem to do this:
Foo foo(std::less<int>());
because T is a class template parameter. I have to use this clunky syntax instead:
Foo<std::less<int>> foo(std::less<int>());
Is there a better way to do this, without writing the type of the functor twice?
Foo is not a class, it is a class template. You have to instantiate it with a template argument in order to create a type.
Concerning your example, you could add a default constructor for functors that are default constructible, like std::less et al.
template <class T>
class Foo {
private:
T func;
public:
Foo() = default; // C++03 would require Foo() {}
Foo(T f) : func(f) { }
};
then
Foo<std::less<int>> foo;
Alternatively, you can provide a function template that takes a functor and returns a Foo<F> object.
You could use a function to deduce the functor type and return the correct Foo flavor:
template <typename T>
Foo<T> make_foo(T t) { return Foo<T>(t); }
but this solution basically needs auto from C++11 to store the return value:
auto f = make_foo(std::less<int>());

What is the meaning of template<> with empty angle brackets in C++?

template<>
class A{
//some class data
};
I have seen this kind of code many times.
what is the use of template<> in the above code?
And what are the cases where we need mandate the use of it?
template<> tells the compiler that a template specialization follows, specifically a full specialization. Normally, class A would have to look something like this:
template<class T>
class A{
// general implementation
};
template<>
class A<int>{
// special implementation for ints
};
Now, whenever A<int> is used, the specialized version is used. You can also use it to specialize functions:
template<class T>
void foo(T t){
// general
}
template<>
void foo<int>(int i){
// for ints
}
// doesn't actually need the <int>
// as the specialization can be deduced from the parameter type
template<>
void foo(int i){
// also valid
}
Normally though, you shouldn't specialize functions, as simple overloads are generally considered superior:
void foo(int i){
// better
}
And now, to make it overkill, the following is a partial specialization:
template<class T1, class T2>
class B{
};
template<class T1>
class B<T1, int>{
};
Works the same way as a full specialization, just that the specialized version is used whenever the second template parameter is an int (e.g., B<bool,int>, B<YourType,int>, etc).
template<> introduces a total specialization of a template. Your example by itself isn't actually valid; you need a more detailed scenario before it becomes useful:
template <typename T>
class A
{
// body for the general case
};
template <>
class A<bool>
{
// body that only applies for T = bool
};
int main()
{
// ...
A<int> ai; // uses the first class definition
A<bool> ab; // uses the second class definition
// ...
}
It looks strange because it's a special case of a more powerful feature, which is called "partial specialization."
Doesn't look right. Now, you might have instead written:
template<>
class A<foo> {
// some stuff
};
... which would be a template specialisation for type foo.

Function template with an operator

In C++, can you have a templated operator on a class? Like so:
class MyClass {
public:
template<class T>
T operator()() { /* return some T */ };
}
This actually seems to compile just fine, but the confusion comes in how one would use it:
MyClass c;
int i = c<int>(); // This doesn't work
int i = (int)c(); // Neither does this*
The fact that it compiles at all suggests to me that it's doable, I'm just at a loss for how to use it! Any suggestions, or is this method of use a non-starter?
You need to specify T.
int i = c.operator()<int>();
Unfortunately, you can't use the function call syntax directly in this case.
Edit: Oh, and you're missing public: at the beginning of the class definition.
You're basically right. It is legal to define templated operators, but they can't be called directly with explicit template arguments.
If you have this operator:
template <typename T>
T operator()();
as in your example, it can only be called like this:
int i = c.operator()<int>();
Of course, if the template argument could be deduced from the arguments, you could still call it the normal way:
template <typename T>
T operator()(T value);
c(42); // would call operator()<int>
An alternative could be to make the argument a reference, and store the output there, instead of returning it:
template <typename T>
void operator()(T& value);
So instead of this:
int r = c.operator()<int>();
you could do
int r;
c(r);
Or perhaps you should just define a simple get<T>() function instead of using the operator.
Aren't you thinking of
class Foo {
public:
template<typename T>
operator T() const { return T(42); }
};
Foo foo;
int i = (int) foo; // less evil: static_cast<int>(foo);
live example. This proves you do not need to specify the template argument, despite the claim in the accepted answer.