【问题标题】:Different member function definition according to compile-time condition根据编译时条件定义不同的成员函数
【发布时间】:2019-04-30 13:19:57
【问题描述】:

根据this answer,我一直在使用

template <typename T,
          typename = typename enable_if<bool_verfier<T>()>::type> >
classMember(const T& arg);

作为多个类成员的函数签名,其中bool_verifier&lt;T&gt;() 是一个模板函数,它断言特定类T 满足某些要求,返回类型为constexpr bool。这确保了 classMember(const T&amp; arg) 的特定重载仅用于特定的参数类型,但是当有多个具有相同原型/参数签名的重载时,不可能这样做,因为编译器不允许这样做:

// ...
template <typename T, typename = typename enable_if<bool_verfier<T>()>::type> >
classMember(const T& arg);
template <typename T,  typename = typename enable_if<!(bool_verfier<T>())>::type>>
classMember(const T& arg);
// ...

导致以下编译错误:

 ‘template<class T, class> void myClass::classMember<T>(const T&)’
 cannot be overloaded with
‘template<class T, class> void std::myClass<T>::classMember(const T&)’

如果我需要classMember 根据bool_verifier&lt;T&gt;() 是否返回true 有不同的定义,那么正确的语法/成员声明是什么?或者,有没有办法从#if 预编译器条件语句中调用bool_verifier&lt;T&gt;

【问题讨论】:

  • “因为编译器不允许”。一如既往,提供minimal reproducible example 和错误消息...
  • @VittorioRomeo 大概是因为 enable if 被设置为默认值,这不是签名的一部分,导致重新定义
  • 你有 C++17 吗?
  • @PiotrSkotnicki:当然,但是 OP 需要把它放在问题中。我们不应该做猜测
  • @VittorioRomeo 编译器不会精确地允许,因为没有编译器会接受具有相同原型的函数重载。我已经编辑了问题。

标签: c++ c++11 templates typetraits overloading


【解决方案1】:

或者,有没有办法从#if 预编译器条件语句调用bool_verifier&lt;T&gt;

不。预处理器在其他任何东西之前运行,并且根本不了解 C++。


您可能需要使用额外的模板参数(或通过更改 enable_if 出现的位置)来消除两个重载之间的歧义,因为默认模板参数值不是签名的一部分。以下对我有用:

struct foo
{
     template <typename T, typename = std::enable_if_t<bool_verifier<T>{}>> 
     void a();

     template <typename T, typename = std::enable_if_t<!bool_verifier<T>{}>, typename = void> 
     void a();
};

live godbolt.org link

【讨论】:

  • 虽然这似乎适用于重载/模板解析,但如果我在 arg 的类型为 std::vector&lt;int&gt; 时在第一次重载中调用 arg.dim(),则会导致编译错误 has no member named dim() ,尽管在这种情况下会使用第二个重载,因为 bool_verifier 将返回 false
  • 另外,这似乎是一个单独的问题。请将其标记为已解决,并发布一个带有正确 MCVE + 编译器错误的新问题。
猜你喜欢
  • 1970-01-01
  • 2011-10-21
  • 2015-09-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多