简体   繁体   中英

Calling a templated functor in a class template

Is there any way to call the functor operator()( int ) of a the class template Foo as shown below ( online version )

template<typename T>
struct Foo
{
    template<typename U>
    void operator()( int )
    {
    }
};

int main(int argc, char *argv[])
{
    Foo<char> foo;
    foo<bool>( 42 );
}

I'm getting the error message in gcc 4.9.3

error: expected primary-expression before ‘bool’
  foo<bool>( 42 );

I'd prepend the functor with template if the member function wasn't a functor and was prefixed with :: , . , or -> . Without some help the compiler couldn't know how to parse this expression ; as a functor or an instantiation of an anonymous object of type foo<int> .

是的,但它很难看:

foo.operator()<bool>( 42 );

It would work with;

foo.operator()<bool>( 42 );

Operators play best with deduced template argument types.

You don't give enough detail of the context in which this is used, as alternatives you could consider;

  • making the call operator a member function and thus allow explicit template type arguments
  • a tag dispatch mechanism
  • accept the type U as an argument

For example;

template<typename U>
void operator()( int, U&& /*initial*/ )
{
  // use the initial value of U
}
// called as...

foo(42, true); // U is bool in your example

Or simply the member function;

template<typename U>
void my_func( int )
{
}
// called as...

foo.my_fun<bool>( 42 );

Unfortunately you'd need to use foo.operator()<bool>(42); for this. foo<bool> is valid for things like C++14 variable templates, not template call operators.

What you could do is tag the type and pass that in as an argument to the call operator to deduce the right type:

//tag
template <typename T>
struct type{};

template<typename T>
struct Foo
{
    template<typename U>
    //deduction on the tagged type
    void operator()( type<U>, int )
    {
    }
};

int main(int argc, char *argv[])
{
    Foo<char> foo;
    foo( type<bool>{}, 42 );
    //   ^^^^^^^^^^^^ pass tag
}

You could make this a bit nicer using C++14 variable templates for the tag:

template <typename T>
struct type_t{};

//variable template for nicer usage
template <typename T>
type_t<T> type;

template<typename T>
struct Foo
{
    template<typename U>
    void operator()( type_t<U>, int )
    {
    }
};

int main(int argc, char *argv[])
{
    Foo<char> foo;
    foo( type<bool>, 42 );
    //don't need {}^
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM