如何根据类模板参数专门化成员函数

发布于 2024-09-14 23:29:35 字数 293 浏览 8 评论 0原文

问题说了什么。另外,是否可以内联执行此操作?

这是一个小例子,只是为了提供一个想法......

template<typename T>
class Foo {
 public:
  Foo() :z(0.0) {}

  void do( const Foo<T> &f ) {
    z = f.z;
  }
  // specialize 'do' for Foo<int>, possible inline?

 private:
  T z;
};

What the question says. In addition, is it possible to do this inline?

Here is a small example just to give an idea...

template<typename T>
class Foo {
 public:
  Foo() :z(0.0) {}

  void do( const Foo<T> &f ) {
    z = f.z;
  }
  // specialize 'do' for Foo<int>, possible inline?

 private:
  T z;
};

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

手长情犹 2024-09-21 23:29:35

你不需要做任何复杂的事情。只需使用重载和委托即可。请注意,我们不能只添加一个 int 重载,因为当 T 结果也是 int 时,这将是一个无效的重载(两个函数 。

template<typename T>
class Foo {
 public:
  Foo() :z(0.0) {}

  void doIt(const Foo<T> &f ) {
    doItImpl(f);
  }

 private:
  template<typename U>
  void doItImpl(const Foo<U> &f) {
    z = f.z;
  }

  void doItImpl(const Foo<int> &f) {
    /* ... */
  }

 private:
  T z;
};

或者,对于这种情况,您可以通过专门化来做到这

template<typename T>
class Foo {
 public:
  Foo() :z(0.0) {}

  void doIt(const Foo<T> &f ) {
    z = f.z;
  }

 private:
  T z;
};

template<>
inline void Foo<int>::doIt(const Foo<int> &f) {
  /* ... */
}

一点 只有当所有模板参数都固定时,才可以使用这种专门化方式 换句话说,部分专门化成员函数是不可能的。

You don't need to do anything complicated. Just use overloading and delegation. Note that we cannot just add an int overload, because when T turns out to be int too, this would be an invalid overload (two functions with the same signature)

template<typename T>
class Foo {
 public:
  Foo() :z(0.0) {}

  void doIt(const Foo<T> &f ) {
    doItImpl(f);
  }

 private:
  template<typename U>
  void doItImpl(const Foo<U> &f) {
    z = f.z;
  }

  void doItImpl(const Foo<int> &f) {
    /* ... */
  }

 private:
  T z;
};

Or, for this case, you can do this by specialization

template<typename T>
class Foo {
 public:
  Foo() :z(0.0) {}

  void doIt(const Foo<T> &f ) {
    z = f.z;
  }

 private:
  T z;
};

template<>
inline void Foo<int>::doIt(const Foo<int> &f) {
  /* ... */
}

Using specialization this way is only possible if all template arguments are fixed. In other words, partially specializing the member function is not possible.

淡莣 2024-09-21 23:29:35

您可以通过使成员函数成为成员函数模板并使用 SFINAE(替换失败不是错误)来获得此行为。例如:

template <typename U>
typename std::enable_if<!std::is_integral<U>::value && 
                        std::is_same<T, U>::value, void>::type
f(const Foo<U>& x)
{
}

template <typename U>
typename std::enable_if<std::is_integral<U>::value && 
                        std::is_same<T, U>::value, void>::type
f(const Foo<U>& x)
{
}

is_integral类型特征测试U是否是整数类型。如果不是,则实例化第一个;如果是,则实例化第二个。

is_same 类型特征测试可确保 TU 是同一类型。这用于确保不会为 Foo 之外的任何类型实例化成员函数模板。

此示例使用 C++0x 库; Boost 还有类型特征库 您可以使用它,其工作原理基本相同。

You can sort of get this behavior by making the member function a member function template and using SFINAE (substitution failure is not an error). For example:

template <typename U>
typename std::enable_if<!std::is_integral<U>::value && 
                        std::is_same<T, U>::value, void>::type
f(const Foo<U>& x)
{
}

template <typename U>
typename std::enable_if<std::is_integral<U>::value && 
                        std::is_same<T, U>::value, void>::type
f(const Foo<U>& x)
{
}

The is_integral type trait test whether U is an integer type. If it is not, the first is instantiated; if it is, the second is instantiated.

The is_same type trait tests to ensure T and U are the same type. This is used to ensure that the member function template is not instantiated for any type other than Foo<T>.

This example makes use of the C++0x <type_traits> library; Boost also has a type traits library that you can use, which works mostly the same.

一片旧的回忆 2024-09-21 23:29:35

您可以尝试做这样的事情(没有测试,可能不起作用):

template<typename T>
class Foo {
 public:
  Foo() :z(0.0) {}

  template<typename Ty = T>
  void do( const Foo<T> &f ) {
    z = f.z;
  }

  template<>
  void do<int>( const Foo<T> &f ) {
    //specialized code
  }

 private:
  T z;
};

You may try to do something like this (didn't test, might not work):

template<typename T>
class Foo {
 public:
  Foo() :z(0.0) {}

  template<typename Ty = T>
  void do( const Foo<T> &f ) {
    z = f.z;
  }

  template<>
  void do<int>( const Foo<T> &f ) {
    //specialized code
  }

 private:
  T z;
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文