C++ 模板函数特化与模板

C++ Templated function specialization with template

我有一个用于 STL 容器的模板化函数。但是,我想将此函数专门用于模板化 class。我该怎么做呢?我坚持使用 C++11。

编辑:更新了代码示例。当 F 是像 int 这样的 POD 时,它似乎可以工作,但在下面的代码示例中被破坏,其中 F 是 class.

#include <vector>
#include <iostream>

template <class F>
class Temp {
  private:
    F f;

  public:
    Temp(F f) : f(f) {}
};

template <typename C, typename F>
struct MyClass {
  MyClass (const C& c, const F& f) { }
 
  operator C() const
    { return {}; }
};

// Base Template Function
template <typename C, typename F>
MyClass<C, F> operator| (const C & left, const F & right)
{
  std::cout << "Generic version" << std::endl;
  
  return MyClass<C, F>(left, right);
}

// Overload that I tried (ignored and used base template function instead)
template <typename C, typename F>
MyClass<C, F> operator| (const MyClass<C, F> & left, const F & right)
{
  std::cout << "MyClass overload" << std::endl;
 
  return MyClass<C, F>(C(left), right);
}

template <class F>
Temp<F> filter(F f) {
  return Temp<F>(f);
}

int main ()
{
  std::vector<int> v0 = { 1, 2, 3 };
  auto m0 = v0
    | filter([] (int i) {return i > 0;});
  auto m1 = m0
    | filter([] (int i) {return i < 3;});
  return 0;
}

以上代码示例打印 Generic version 两次。

您不能部分特化模板函数。

但是你的重载应该有效。

我修改了你的 MyClass class 使其编译,但在下面的示例中,重载版本负责。

#include <iostream>

template <typename C, typename F>
struct MyClass
 {
   template <typename ... Ts>
   MyClass (Ts const & ...) 
    { }

   operator C() const
    { return {}; }
 };


/* Base Template Function */
template <typename C, typename F>
MyClass<C, F> operator| (C const & left, F const & right)
 {
   std::cout << "Generic version" << std::endl;

   return MyClass<C, F>(left, right);
 }

/* Overload that I tried (ignored and used base template function instead) */
template <typename C, typename F>
MyClass<C, F> operator| (MyClass<C, F> const & left, F const & right)
 {
   std::cout << "MyClass overload" << std::endl;

   return MyClass<C, F>(C(left), right);
 }

int main ()
 { 
   MyClass<int, int> m0;

   auto x = m0 | 0;

   static_assert( std::is_same_v<decltype(x), MyClass<int, int>>, "!" );
 }