2

How does one implicitly call a class object's templated function call operator?

class User_Type
{
public:
    template< typename T > T operator()() const;
};

void function()
{
    User_Type user_var;
    int int_var_0 = user_var.operator()< int >(); // explicit function call operator; ugly.
    int int_var_1 = user_var< int >(); // implicit function call operator.
}

g++-4.9 -Wall -Wextra's output error is:

    error: expected primary-expression before ‘int’
        auto int_var_1 = user_var< int >();
                                   ^
Charles L Wilcox
  • 1,126
  • 8
  • 18
  • What is the point of this if you have 'implicit conversions' (as you mentioned in a comment) ? –  Nov 11 '14 at 18:07
  • @DieterLücking I want a symbol to act as a "conceptual value", and know how to represent itself as many different types. – Charles L Wilcox Nov 11 '14 at 18:18
  • @DieterLücking Think of the statement `T val = 0`; this is valid for any fundamental type. I want to provide a `T val = foo` that is valid for any fundamental type, and user-extended types. In my case `foo` is a namespace static instance of class `Foo`. – Charles L Wilcox Nov 11 '14 at 18:21

2 Answers2

4

If the template argument needs to be specified explicitly, then you can't. The only way to specify it is to use your first syntax.

If the template argument can be deduced from the function arguments, or has a default, then you can use simple function-call syntax if you want that argument.

Depending on what the type is used for, it might make sense to make the class, rather than the member, a template, so you can specify the argument when declaring the object.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • That's a real bummer. *sigh* Do you happen to have a keyword or a full chapter & paragraph reference into the Standard doc which might explain this? – Charles L Wilcox Nov 11 '14 at 17:26
  • My class itself cannot take one template parameter; it acts as an object that can be converted to `T`, by definition. – Charles L Wilcox Nov 11 '14 at 17:27
  • My class already has `template< typename T > operator T () const` defined, which works when implicit conversions work. I wanted another method to provide an explicit syntax. :-/ – Charles L Wilcox Nov 11 '14 at 17:29
  • 1
    @CharlesLWilcox why not use a template explicit conversion operator ? Edit : what's wrong with calling the conversion operator explicitly ? – Quentin Nov 11 '14 at 17:29
  • 2
    @CharlesLWilcox: I'd use a function template called `as` or something for that. `user_var.as()` is perhaps a nicer idiom than `user_var()` in any case. – Mike Seymour Nov 11 '14 at 17:30
  • @Quentin, I've defined the *conversion operator*. However, `static_cast< T >( user_var )` can be ambiguous, depending upon `T`'s defined *conversion constructors*. – Charles L Wilcox Nov 11 '14 at 17:33
  • 1
    @CharlesLWilcox indeed. – Quentin Nov 11 '14 at 17:35
  • I still wish I knew why there was this syntactic limitation, but I guess I have to accept it. `std::reference_wrapper`, and `boost::optional` both use an explicit `get` operator, instead of a function-call operator. – Charles L Wilcox Nov 14 '14 at 15:24
0

There is just no way. it's possible to cheat a bit with a non-used parameter like

class User_Type
{
public:
    template< typename T > T operator()( T * ) const;
};

void function()
{
    User_Type user_var;
    int int_var_1 = user_var((int*)0); // implicit function call operator.
}

but it will not be what you precisely want.

dev_null
  • 1,907
  • 1
  • 16
  • 25