代码之家  ›  专栏  ›  技术社区  ›  Peter Ruderman

C++中有没有方法引用函数模板,既不调用它也不提供模板参数?

  •  2
  • Peter Ruderman  · 技术社区  · 6 年前

    下面是我想要的代码:

    template <class T> void Foo(T&& param);
    
    template <class F> void CallMe(F&& func)
    {
        func(42);
    }
    
    int main()
    {
        CallMe(Foo);
    }
    

    编译器尝试实例化时阻塞 CallMe 因为它不知道我的意思 Foo . 如果我写的话就行了 Foo<int> 当然,但我想避免这种情况,因为在实际代码中,模板参数可能很复杂。

    我目前的解决方法是使用可调用对象而不是自由函数。例如:

    class Foo
    {
      public:
        template <class T> void operator()(T&&);
    };
    

    这很好,但我确信它会让我的库的用户感到困惑。有一些模板魔术我可以用来使第一个版本的工作?

    4 回复  |  直到 5 年前
        1
  •  5
  •   Barry    6 年前

    我希望如此。我希望有一天。在这方面有几项建议(例如:。 P0119 P0834 ). 在此之前,您最好编写一个提升宏来 名称 到调用该名称的函数对象中:

    #define FWD(...) std::forward<decltype(__VA_ARGS__)>(__VA_ARGS__)
    #define LIFT(name) [&](auto&&... args)     \
        noexcept(noexcept(name(FWD(args)...))) \
        -> decltype(name(FWD(args)...))        \
        { return name(FWD(args)...); }
    

    您可以这样写:

    CallMe(LIFT(Foo));
    

    否则你想怎么做就怎么做。

        2
  •  2
  •   Michael Veksler    6 年前

    int main()
    {
        CallMe(Foo);
    }
    

    需要一个对象作为参数。对象可以是函数指针、类实例、lambda或类似的东西。它不能是未实例化的模板函数,因为它不是对象。只有实例化的函数才是对象。

    class Foo
    {
      public:
        template <class T> void operator()(T&&);
    };
    

    取而代之的是,它可以使用一个通用的lambda,这是基本相同的,但没有所有的锅炉板。泛型lambda看起来几乎像一个正则函数:

    auto Foo = [](auto x) 
    { 
       std::cout << x << '\n';
    };
    int main()
    {
       CallMe(Foo);
    }
    
        3
  •  1
  •   Jans    6 年前

    有一些模板魔术我可以用来使第一个版本的工作?

    不。

    函数模板的名称不是函数类型的名称,而是函数族的名称。如果可能的话 func 将从 Foo 类型 T

        4
  •  0
  •   Yakk - Adam Nevraumont    6 年前
    #define RETURNS(...) \
      noexcept(noexcept(__VA_ARGS__)) \
      -> decltype(__VA_ARGS__) \
      { return __VA_ARGS__; }
    
    #define OVERLOADS_OF(...) \
      [](auto&&...args) \
      RETURNS( __VA_ARGS__( decltype(args)(args)... ) )
    

    然后

    CallMe(OVERLOADS_OF(Foo));
    

    创建表示名称重载的函数对象 Foo ,其中包括由名为 .

    RETURNS 在其他情况下也很有用。 @Barry has a proposal 使 RETURNS(X) 类似 => X