c++ 为什么SFINAE(enable_if)不适用于类模板的成员函数?

8cdiaqws  于 2024-01-09  发布在  其他
关注(0)|答案(1)|浏览(133)

此问题在此处已有答案

std::enable_if to conditionally compile a member function(9个回答)
Why class template instantiation fails for unused member template function and implicit instantiation of member function's declaration(3个答案)
8天前关闭.

  1. #include <type_traits>
  2. struct A{};
  3. struct B{};
  4. template <typename T>
  5. struct Foo
  6. {
  7. typename std::enable_if<std::is_same<T, A>::value>::type
  8. bar()
  9. {}
  10. typename std::enable_if<std::is_same<T, B>::value>::type
  11. bar()
  12. {}
  13. };

错误消息:

  1. 14:5: error: 'typename std::enable_if<std::is_same<T, B>::value>::type Foo<T>::bar()' cannot be overloaded 10:5:
  2. error: with 'typename std::enable_if<std::is_same<T, A>::value>::type Foo<T>::bar()'


cpp.sh上的源代码。我认为两个typename std::enable_if<std::is_same<T,?>::value>::type不能同时有效。

编辑

对于后人来说,这是我根据@KerrekSB的回答进行的编辑-SFINAE只适用于推导的模板参数

  1. #include <type_traits>
  2. struct A{};
  3. struct B{};
  4. template<typename T>
  5. struct Foo
  6. {
  7. template<typename U = T>
  8. typename std::enable_if<std::is_same<U,A>::value>::type
  9. bar()
  10. {
  11. }
  12. template<typename U = T>
  13. typename std::enable_if<std::is_same<U,B>::value>::type
  14. bar()
  15. {
  16. }
  17. };
  18. int main()
  19. {
  20. };

zwghvu4y

zwghvu4y1#

SFINAE只适用于 * derived * 模板参数,即函数模板。在您的情况下,两个模板都是无条件示例化的,并且示例化失败。
以下变体可以工作:

  1. struct Foo
  2. {
  3. template <typename T>
  4. typename std::enable_if<std::is_same<T, A>::value>::type bar(T) {}
  5. // ... (further similar overloads) ...
  6. };

字符串
现在Foo()(x)最多只会导致一个重载被示例化,因为参数替换在所有其他重载中都失败了。
如果你想坚持你的原始结构,使用显式的类模板专门化:

  1. template <typename> struct Foo;
  2. template <> struct Foo<A> { void bar() {} };
  3. template <> struct Foo<B> { void bar() {} };

展开查看全部

相关问题