1

This issue occurred to me from an other piece of code but it boils down to this snippet:

#include <iostream>

struct A
{
    template <int I>
    A() : _i{I} {}

    int _i;
};

int main()
{
    A* ptr = new A; // how to call the constructor with a specific template argument ?

    return 0;    
}

This will not surprisingly raise the following error:

clang++ -std=c++17 -Wall main.cpp && ./a.out;

main.cpp:13:18: error: no matching constructor for initialization of 'A'

    A* ptr = new A; // how to call the constructor with a specific template argument ?
                 ^
main.cpp:6:5: note: candidate template ignored: couldn't infer template argument 'I'

    A() : _i{I} {}
    ^
main.cpp:3:8: note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 0 were provided

struct A
       ^

This looks like an issue that would have been encountered a thousand times before but I couldn't find the solution on cppreference or SO.

How to specify constructor's template arguments inside a new expression ?

matovitch
  • 1,264
  • 11
  • 26
  • What is the purpose of using a templated constructor instead of a templated class? Perhaps that could be solved by using inheritance, where the child-class is a template? – Some programmer dude Aug 16 '19 at 13:04
  • @Someprogrammerdude Essentially I want to provide a kind of view over a typed array and I want to be able to create these views from std::arrays of any size (hence the templated constructor). I could provide details if needed. But that's not the question. :P Let say I want to do it, how can use new if the template argument of the constructor fail to be deduced ? – matovitch Aug 16 '19 at 13:08

3 Answers3

4

Unfortunately, you can't specify template arguments explicitly for constructor template, which can't be used unless the template parameters could be deduced. [temp.arg.explicit]/8

[ Note: Because the explicit template argument list follows the function template name, and because constructor templates ([class.ctor]) are named without using a function name ([class.qual]), there is no way to provide an explicit template argument list for these function templates. — end note ]

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
2

You have to deduce it. You cannot pass them explicitly.

One solution for your example would be:

struct A
{
    template <int I>
    A(std::integral_constant<int, I>) : _i{I} {}

    int _i;
};

auto a = A{std::integral_constant<int, 4>{}};
Guillaume Racicot
  • 39,621
  • 9
  • 77
  • 141
  • Indeed thanks, or based on your idea, I could use a dummy 'tag' like this http://coliru.stacked-crooked.com/a/6ad797ec94427693. I think that is what I will use for my case. – matovitch Aug 16 '19 at 13:33
1

As mentioned in my comment, a possible workaround could be to use inheritance:

struct A
{
    int _i;
};

template<int I>
struct B : A
{
    B() : A::_i(I) {}
};

...

A* a = new B<10>;
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621