在类模板中调用模板化仿函数

时间:2016-02-09 11:11:48

标签: c++ templates

有没有办法调用类模板operator()( int )的仿函数Foo,如下所示(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 );
}

我在gcc 4.9.3

中收到错误消息
error: expected primary-expression before ‘bool’
  foo<bool>( 42 );

如果成员函数不是函子并且以template::.为前缀,我会在->之前添加仿函数。没有一些帮助,编译器就不会知道如何解析这个表达式;作为类型为foo<int>的匿名对象的仿函数或实例化。

3 个答案:

答案 0 :(得分:5)

是的,但它很难看:

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

答案 1 :(得分:5)

可以使用;

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

运算符最适合使用推导出的模板参数类型。

您没有详细介绍使用此功能的上下文,作为您可以考虑的替代方案;

  • 使调用操作符成为成员函数,从而允许显式模板类型参数
  • 标签发送机制
  • 接受类型U作为参数

例如;

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

或者只是成员函数;

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

foo.my_fun<bool>( 42 );

答案 2 :(得分:3)

很遗憾,您需要使用foo.operator()<bool>(42);foo<bool>适用于C ++ 14变量模板,而不是模板调用操作符。

你可以做的是标记类型并将其作为参数传递给调用操作符以推断出正确的类型:

//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
}

使用标签的C ++ 14变量模板可以使这更好一些:

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 {}^
}