Home > front end >  Templated constructor not accessible in struct
Templated constructor not accessible in struct

Time:12-23

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
  • Related