具有类成员函数的返回类型的enable_if

时间:2019-02-16 11:46:27

标签: c++ enable-if

我正在尝试一种基于类模板参数来专门化成员函数的方法,而不必在类上使用SFINAE(并导致代码重复或创建另一个类)。

由于两个模板参数不能是可选的,并且准则中不赞成使用参数enable_if,因此我尝试了以下两种方法(其余):

template <bool boolean = true>
struct sample {
    constexpr typename std::enable_if<boolean, int>::type bool_check_return(
        int s) const noexcept {
        return s + 1;
    }
    constexpr typename std::enable_if<!boolean, int>::type bool_check_return(
        int s) const noexcept {
        return s;
    }

    template <typename std::enable_if<boolean, int>::type = 0>
    int bool_check_template(
        int s) const noexcept {
        return s + 1;
    }
    template <typename std::enable_if<!boolean, int>::type = 0>
    int bool_check_template(
        int s) const noexcept {
        return s;
    }
};

Godbolt link

在我看来,为什么返回类型SFINAE给出以下有关“重载不适用于仅返回类型不同的函数”的错误,这在我看来似乎并不明显。 SFINAE应该只确保一份副本,而不是两份。

我不知不觉违反了标准的哪一部分?还是这是编译器错误?实际上,在C ++ 17中,if constexpr不会有问题(并且由于一种形式有效,所以我可以选择该形式)。

此错误出现在C ++ 11到C ++ 17中,这使得编译器对此错误的可能性很小。

error: functions that differ only in their return type cannot be overloaded
    constexpr typename std::enable_if<!boolean, int>::type bool_check_return(
              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^
note: previous definition is here
    constexpr typename std::enable_if<boolean, int>::type bool_check_return(
              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^
1 error generated.

2 个答案:

答案 0 :(得分:1)

此处未涉及SFINAE,因为bool_check_return本身不是模板。它们只是常规的重载函数,仅在返回类型上有所不同。制作它们的模板可以通过只允许其中之一来解决问题:

template<bool enabled = boolean>
constexpr typename std::enable_if<enabled, int>::type bool_check_return(
    int s) const noexcept {
    return s + 1;
}

template<bool enabled = boolean>
constexpr typename std::enable_if<not enabled, int>::type bool_check_return(
    int s) const noexcept {
    return s;
}

答案 1 :(得分:0)

编译器是正确的。无论如何,即使替换后只有一个返回类型有效,也不能重载具有相同返回类型的两个函数。

来自[over.load]

  

某些函数声明不能​​重载:

     
      
  • 仅在返回类型,异常说明或两者上不同的函数声明不能​​重载。
  •   
  • ...
  •   

此规则也不例外。