在bool值

时间:2016-12-02 10:02:42

标签: c++ templates overloading metaprogramming typetraits

我试图避开项目主分支上的概念,所以我需要type_trait的某种替代方案:

我需要一个类,其中一些函数会根据bool值而改变。

有人已经建议我分开我的课,但这个案例在这里没有意义。对于某些上下文,如果可以共享池的对象类型,则删除函数和其他一些池将会更改。

所以我尝试使用std::enable_if,但仍然存在一些错误(我希望声明和实现分开)。

#include  <type_traits>

template < typename Object, bool Shared = false >
class Foo {

  template < bool S = Shared, typename std::enable_if<S>::type* = nullptr >
  void   bar();

  template < bool S = Shared, typename std::enable_if<!S>::type* = nullptr >
  void   bar();
};

template < typename Object,
           bool Shared >
template < bool S, typename std::enable_if<S>::type* = nullptr >
void   Foo<Object, Shared>::bar() {
    //do something
}


template < typename Object,
           bool Shared >
template < bool S, typename std::enable_if<!S>::type* = nullptr >
void   Foo<Object, Shared>::bar() {
  //do nothing
}

int main() {

  Foo<int> test;
  return 0;
}
Test3.cpp:16:33: error: default argument for template parameter for class enclosing ‘void Foo<Object, Shared>::bar()’
 void   Foo<Object, Shared>::bar() {
                                 ^
Test3.cpp:24:33: error: default argument for template parameter for class enclosing ‘void Foo<Object, Shared>::bar()’
 void   Foo<Object, Shared>::bar() {

编辑:删除了复制/粘贴错误

4 个答案:

答案 0 :(得分:4)

1.对于成员函数声明类定义中,应删除类名(即Foo<Object, Shared>::)的限定。

2. Default template arguments不允许用于成员模板的类外定义,只需将其删除即可。

  

不允许使用默认参数

     
      
  • 在成员模板的类外定义中(必须是   在类体内的声明中提供)
  •   

然后

template < typename Object, bool Shared = false >
class Foo {

  template < bool S = Shared, typename std::enable_if<S>::type* = nullptr >
  void  bar();

  template < bool S = Shared, typename std::enable_if<!S>::type* = nullptr >
  void  bar();
};

template < typename Object,
           bool Shared >
template < bool S, typename std::enable_if<S>::type*  >
void   Foo<Object, Shared>::bar() {
    //do something
}

template < typename Object,
           bool Shared >
template < bool S, typename std::enable_if<!S>::type* >
void   Foo<Object, Shared>::bar() {
  //do nothing
}

LIVE

答案 1 :(得分:1)

以下是您的代码一旦修复(最小,工作示例):

$(document).on('click', '#buttonSelector', function () {
    $(this).addClass('disabled');
});

这是一个额外限定符和默认参数的问题,不能在类定义之外重复。

答案 2 :(得分:1)

另外请注意,这是一个更清洁的解决方案:

#include <type_traits>
#include <iostream>

template<bool b>
using allow_if = typename std::enable_if<b>::type;

template <typename Object, bool Shared = false>
class Foo {
public:
    template<bool S = Shared>
    allow_if<S> bar();

    template<bool S = Shared>
    allow_if<!S> bar();
};

template<typename Object, bool Shared>
template<bool S>
allow_if<S> Foo<Object, Shared>::bar() {
    std::cout << "do something" << std::endl;
}

template<typename Object, bool Shared>
template<bool S>
allow_if<!S> Foo<Object, Shared>::bar() {
    std::cout << "do nothing" << std::endl;
}

int main() {
    Foo<int> test;
    test.bar<>();
    test.bar<true>();
    return 0;
}

答案 3 :(得分:1)

作为替代方案,您可以使用tag-dispatching:

template <typename Object, bool Shared = false>
class Foo {
public:
    void bar() { bar(std::integral_constant<bool, Shared>{}); }

private:
    void bar(std::true_type);
    void bar(std::false_type);
};

template <typename Object, bool Shared>
void Foo<Object, Shared>::bar(std::true_type) { /**/ }

template <typename Object, bool Shared>
void Foo<Object, Shared>::bar(std::false_type) { /**/ }

从C ++ 17开始,您可以使用if constexpr

template <typename Object, bool Shared = false>
class Foo {
public:
    void bar() {
        if constexpr (Shared) {
            // ...
        } else {
            // ...
        }
    }

所以每个块只能以正确的版本提供:

  • 所以没有运行时分支(我希望在您的情况下,无论如何都要优化常规分支)
  • 未选择的块可能包含仅在选择该分支时有效的代码(当它取决于类型时非常有用)。