Templated constructor is not accessible in struct. I would like to allow for non-templated construction still, if possible. If its not possible I would like to understand what wall this actually is in the language, if any..
The error is this: Expected '(' for function-style cast or type construction
It's a syntax error. How you construct with a template is name(args), and that is exactly what:
A a = A<short>(1);
... is doing, right?
#include <iostream>
struct A {
int i;
A() : i(0) { }
template <typename T>
A(T i) : i(int(i)) { }
void print() {
std::cout << i << std::endl;
}
};
int main() {
A a = A<short>(1);
a.print();
return 0;
}
-- EDIT --
Adding the #1 problem I ran into at first. The answer came quick but theres a bit more nuance here. Let me describe it better.
struct A {
std::function<int(int)> fn;
template <typename T>
A() {
fn = [](int i) {
/// merely using T somewhere in this lambda
return int(T(i));
};
}
};
int main(int c, const char *v[]) {
A a = A<int>();
}
I originally stated it must have the default constructor but I wasn't actually needing it that way. I am, however not directly referencing the template param in any argument and I know why that must be what I'm stuck with?
-- EDIT 3 --
I simply needed a class-mode template setup in my case. The reason I was a bit stubborn was the need to keep a bit of code out of the header.
CodePudding user response:
The templated constructor will be selected if you construct A from a short explictly
#include <iostream>
struct A
{
int i;
A() : i(0) { }
// i(int(i)) { } <== do NOT use "C" style casts in C
template <typename T>
A(T v) :
i{ static_cast<int>(v) }
{
std::cout << "using templated constructor\n";
}
void print() {
std::cout << i << std::endl;
}
};
int main()
{
A a{ short{1} }; // construct a from a short
a.print();
return 0;
}
CodePudding user response:
A
is a non-template class, so you can't specify template argument for it like A<short>
. And there's no way to specify template argument for constructor template; template argument could only be deduced from constructor argument.
So you can
A a = A(1); // T will be deduced as int
// if pass a short like static_cast<short>(1) T will be deduced as short
Or just
A a(1); // T will be deduced as int
// if pass a short like static_cast<short>(1) T will be deduced as short