Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling a templated functor in a class template

Tags:

c++

templates

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>.

like image 713
Olumide Avatar asked Feb 09 '16 11:02

Olumide


People also ask

What is the syntax for class template?

What is the syntax of class template? Explanation: Syntax involves template keyword followed by list of parameters in angular brackets and then class declaration. As follows template <paramaters> class declaration; 2.

What is Typename in template?

" typename " is a keyword in the C++ programming language used when writing templates. It is used for specifying that a dependent name in a template definition or declaration is a type.

Can class template be nested?

Member templates that are classes are referred to as nested class templates. Member templates that are functions are discussed in Member Function Templates. Nested class templates are declared as class templates inside the scope of the outer class. They can be defined inside or outside of the enclosing class.

What is the difference between class template and function template?

For normal code, you would use a class template when you want to create a class that is parameterised by a type, and a function template when you want to create a function that can operate on many different types.

How to use function template in C++ with example?

C++ Function Template 1 Function Template Declaration. A function template starts with the keyword template followed by template parameter (s) inside <> which is followed by function declaration. 2 Calling a Function Template. We can then call it in the main () function to add int and double numbers. 3 Example: Finding the Absolute Value of Numbers

What is the difference between function template and class template?

Similar to function templates, we can use class templates to create a single class to work with different data types. Class templates come in handy as they can make our code shorter and more manageable. A class template starts with the keyword template followed by template parameter (s) inside <> which is followed by the class declaration.

How do I call a function from another function template?

Once we've declared and defined a function template, we can call it in other functions or templates (such as the main() function) with the following syntax. functionName<dataType>(parameter1, parameter2,...); For example, let us consider a template that adds two numbers: template <typename T> T add(T num1, T num2) { return (num1 + num2); }

What are some examples of templates in C++?

Examples of function templates are sort (), max (), min (), printArray (). Below is the program to implement Bubble Sort using templates in C++: Class Templates Like function templates, class templates are useful when a class defines something that is independent of the data type.


3 Answers

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 );
like image 190
Niall Avatar answered Oct 06 '22 11:10

Niall


Yes but it's ugly:

foo.operator()<bool>( 42 );
like image 5
101010 Avatar answered Oct 06 '22 09:10

101010


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 {}^
}
like image 3
TartanLlama Avatar answered Oct 06 '22 11:10

TartanLlama