1

Possible Duplicate:
Can the template parameters of a constructor be explicitly specified?

following up on my previous question, (I found this situation in edit 2)

Laid out simple in code:

#include <iostream>

struct Printer
{
  Printer() { std::cout << "secret code" << std::endl; }
};

template <class A>
struct Class
{
  template <class B, class C>
  Class(B arg)
  {
      C c; /* the 'secret code' should come from here */
      std::cout << arg << std::endl;
  }

  Class(double arg) { std::cout << "double" << std::endl; }
  Class(float arg) { std::cout << "float" << std::endl; }

  /* this forbids the use of printer in the first parameter */
  Class(Printer printer) { throw std::exception(); /* here be dragons */ }
};

int main()
{
  Class<int> c(1.0f);
  Class<int>* ptr = new Class<int>((double)2.0f);
  return 0;
}

// Can anyone print 'secret code' while creating an object of type 'Class' ?

Detailed: For a template constructor, can you specify a template argument which is not part of the constructor's arguments when an object get's instantiated?

I think this deserves a question of its own.

Community
  • 1
  • 1
costy.petrisor
  • 783
  • 7
  • 17

2 Answers2

3

No, it's not possible.

There is no syntax with which you can provide explicit template parameters to a constructor template. You can only provide explicit template parameters for the class template as a whole.

The following text from [temp.arg.explicit] (2003 wording, 14.8.1/5) covers the scenario. Though the clause is non-normative, it serves to explain to us that, as an inherent restriction of the grammar, this is not possible:

Note: because the explicit template argument list follows the function template name, and because conversion member function templates and constructor member function templates are called without using a function name, there is no way to provide an explicit template argument list for these function templates.

This, partially, comes out of the fact that you never actually invoke the constructor explicitly yourself. When you write, say, A() you are not calling the constructor like a function, even though it looks as if you are ("conversion member function templates and constructor member function templates are called without using a function name").

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • 1
    I tend to agree, but when this question was last debated, all that was clear is that the standard itself isn't very clear. – James Kanze Jun 15 '11 at 14:15
  • @James: I don't follow. `int` there is a class template parameter, no? – Lightness Races in Orbit Jun 15 '11 at 14:16
  • @Tomalak Yes. I realized my mistake just as I was clicking on the send button, and have edited my response to delete the part which was wrong. – James Kanze Jun 15 '11 at 14:17
  • @James: I have edited my answer. This is clear by deduction from the grammar, and the standard contains a clear explanation of this deduction. – Lightness Races in Orbit Jun 15 '11 at 14:28
  • @James refers to the discussion he and me had about it. It's true that you cannot provide arguments when *calling* the constructor template (this is a bit imprecise - you *can* actually try to call a ctor directly and then provide template arguments, but directly calling it (i.e with fuction-call syntax) is ill-formed), however explicit arguments can be provided in other contexts (explicit instantiation, explicit specialization). But that isn't really useful on its own :) This assertion of me can be found in the discussion's comment list. – Johannes Schaub - litb Jun 15 '11 at 17:31
  • Insofar, I totally agree with your reasoning, "This, partially, comes out of the fact that you never actually invoke the constructor explicitly yourself.". – Johannes Schaub - litb Jun 15 '11 at 17:34
  • @litb: "you can actually try to call a ctor directly and then provide template arguments, but directly calling it is ill-formed" please explain this. It reads to me as "you can call a ctor directly, but you can't call a ctor directly." – Lightness Races in Orbit Jun 15 '11 at 23:58
  • @Tomalak "i can drive a car, but I'm not allowed to" ("shall not") vs "i cannot drive a car but i'm allowed to" ("cannot", "no able") vs "i cannot drive a car and i'm not allowed to." ("cannot" / "not able" too). Since by 3.4.3.1, `Class::Class` refers to a constructor function template specialization, you can use that in a call (you can call functions). But 3.4.3.1 also says "Such a constructor name shall be used only in the declarator-id of a constructor definition that appears outside of the class definition.". So you are, effectively, not allowed to do the call. – Johannes Schaub - litb Jun 17 '11 at 15:11
  • @litb: Ah, ok. So "you can actually try to call a ctor directly and then provide template arguments, but you shan't." – Lightness Races in Orbit Jun 17 '11 at 15:16
  • Yeah if the goal is to have a well-formed program, then I think one can say "you cannot" :) This is like private/public function calls. For sure you can call an inaccessible function, but you shall not. BTW I'm not notified by your follow-up comments if you use the "@litb" comment because my nick doesn't start with "litb". I don't know what other nice follow-up comments you made in the past that I missed out that way -.- – Johannes Schaub - litb Jun 17 '11 at 15:31
0

I think he want to know how to instantiate this class with C as SomeType:

template<typename A>
class foo
{
    template<typename B, typename C>
    foo(B b)
    {
        C c;
    }
};

I don't know if this is possible.

Mircea Ispas
  • 20,260
  • 32
  • 123
  • 211