c++11 enable_if错误-模板参数重新声明

jdg4fx2g  于 2023-07-01  发布在  其他
关注(0)|答案(2)|浏览(200)

下面是一个例子:

  1. template <class T, typename std::enable_if<!std::is_fundamental<T>::value, int >::type = 0 >
  2. class Calc
  3. {
  4. public:
  5. int operator()( const T& v ) const {
  6. return v.getValue();
  7. }
  8. };
  9. template <class T, typename std::enable_if<std::is_fundamental<T>::value, int >::type = 0 >
  10. class Calc : CalcBase <T>
  11. {
  12. };

在编译时,我得到以下错误:

  1. c.cpp:26: error: template parameter 'typename std::enable_if<(! std::is_fundamental::value), int>::type <anonymous>'
  2. c.cpp:36: error: redeclared here as 'typename std::enable_if<std::is_fundamental::value, int>::type <anonymous>'

这里的目的是选择Calc的版本,如果传递的模板参数是一个类,则该版本将覆盖基类函数调用运算符。如果传递的参数是基本类型,那么我们选择不覆盖基类功能的Calc版本。你能帮助我了解如何让它工作吗?

kuarbcqp

kuarbcqp1#

我不认为类模板声明与SFINAE一起工作:类模板不像函数模板那样被重载。您声明了两个同名的主类模板,这是不允许的。
方便的是,SFINAE对于您的用例不是必需的:类模板支持部分专门化。您只需使用默认的bool参数,并根据trait是true还是false来专门化类模板。例如:

  1. template <class T, bool = std::is_fundamental<T>::value>
  2. class Calc
  3. {
  4. public:
  5. int operator()( const T& v ) const {
  6. return v.getValue();
  7. }
  8. };
  9. template <class T>
  10. class Calc<T, false> : CalcBase <T>
  11. {
  12. };
kmb7vmvb

kmb7vmvb2#

将SFINAE与类模板一起使用的一种方法是通过使用SFINAE专门化模板参数的部分专门化。
下面是一个实现问题中描述的类的最小工作示例。
Calc的示例化中,模板参数U要么具有默认类型void,要么具有类型void,但通过enable_if条件为true,或者如果enable_if条件为false,则涉及SFINAE类型错误。
由于U具有void的默认参数,因此导致所有部分专门化的SFINAE类型错误的类型T仍然会导致基于默认参数的类模板的示例化,并避免编译时错误。注意:在这个特定的例子中,其中一个条件必须是true,但是在其他情况下,使用默认参数会有所帮助。

  1. #include <type_traits>
  2. class NonFundamental {
  3. public:
  4. NonFundamental(int val) : val_(val) {}
  5. int getValue() {
  6. return val_;
  7. }
  8. private:
  9. int val_;
  10. };
  11. template <typename T>
  12. class Calcbase {};
  13. template <typename T, typename U = void>
  14. class Calc {};
  15. template <typename T>
  16. class Calc<T, typename std::enable_if_t<!std::is_fundamental_v<T>>> {
  17. public:
  18. int operator()(const T &v) const {
  19. return v.getValue();
  20. }
  21. };
  22. template <typename T>
  23. class Calc<T, typename std::enable_if_t<std::is_fundamental_v<T>>> : Calcbase<T> {
  24. };
  25. int main() {
  26. Calc<int> calc_obj_1;
  27. Calc<NonFundamental> calc_obj_2;
  28. return 0;
  29. }
展开查看全部

相关问题