3

It's possible to give a templated constructor template parameters that cannot be deduced:

struct X
{
    int i;

    template<int N>
    X() : i(N)
    {
    }
};

How would you use such a constructor? Can you use it at all?

zneak
  • 134,922
  • 42
  • 253
  • 328
  • 3
    You can't. Since constructors don't have names, you can't specify template arguments of constructor templates. All template arguments must be deducible. – Kerrek SB Oct 01 '15 at 16:31
  • 1
    You can of course achieve compile-time constant expression initialization by other means, e.g. tag dispatch with a `std::integral_constant` parameter etc. – Kerrek SB Oct 01 '15 at 16:31
  • What is your use case? –  Oct 01 '15 at 17:18
  • @DieterLücking, I would have used it with a type to wrap the allocation of an object. I'm using a function instead, similar to `make_unique`. – zneak Oct 01 '15 at 17:20

1 Answers1

3

No, you can't specify constructor template arguments. There are a few alternatives.

  1. As indicated in the comments by @KerrekSB, you can give the constructor template a std::integral_constant parameter, which when passed as an argument, will deduce N:

Code:

#include <cassert>
#include <type_traits>

struct X
{
    int i;

    template<int N>
    X(std::integral_constant<int, N>) : i(N)
    {
    }
};

int main()
{
    std::integral_constant<int, 6> six;
    X x(six);
    assert(x.i == 6);
}

Live Example

  1. You can write a dedicated make_X<N> template wrapper that hides the integral_constant boiler-plate:

Code:

template<int N>
X make_X()
{
    return X(std::integral_constant<int, N>{});        
}

int main()
{
    auto y = make_X<42>();
    assert(y.i == 42);
}

Live Example

Community
  • 1
  • 1
TemplateRex
  • 69,038
  • 19
  • 164
  • 304