在实例化类时是否实例化了类模板的成员?

时间:2014-09-03 12:17:19

标签: c++ c++98

假设模板类的成员不应该被实例化,除非它们被使用。 然而,此示例似乎实例化了do_something成员而enable_if失败了(如果我们实例化它会是预期的 - 但我们没有实例化AFAIK)。

我错过了一些非常基本的东西吗?

#include <string>
#include <boost/utility.hpp>

struct some_policy {
    typedef boost::integral_constant<bool, false> condition;
};

struct other_policy {
    typedef boost::integral_constant<bool, true> condition;
};


template <typename policy>
class test {
   void do_something(typename boost::enable_if<typename policy::condition>::type* = 0) {}
};

int main() {
    test<other_policy> p1;
    test<some_policy>  p2;
}

coliru

3 个答案:

答案 0 :(得分:8)

来自C ++ 11 14.7.1 / 1:

  

类模板特化的隐式实例化会导致隐式   实例化类成员函数

的声明,但不包括定义或默认参数

因此实例化了函数声明;失败,因为它取决于无效的类型。

(不幸的是,我没有任何历史版本的标准可供参考,但我想这个规则在C ++ 98中是类似的)

答案 1 :(得分:6)

Mike Seymour已经回答了为什么它不起作用,这里是如何解决它:

#include <string>
#include <boost/utility.hpp>

struct some_policy {
    typedef boost::integral_constant<bool, false> condition;
};

struct other_policy {
    typedef boost::integral_constant<bool, true> condition;
};

template <typename policy>
class test {
private:

   template<typename P>
   void do_something_impl(typename boost::enable_if<typename P::condition>::type* = 0) {}

public:
   void do_something()
   {
       do_something_impl<policy>();      
   }
};

int main() {
    test<other_policy> p1;
    test<some_policy>  p2;
}

快速经验法则:如果你想做SFINAE,你需要一个成员函数 template

答案 2 :(得分:4)

SFINAE仅在模板函数/方法上发生(这里,它是您的类,它是模板),

您可以使用C ++ 11(函数/方法的默认模板参数):

template <typename policy>
class test {
   template <typename T = policy>
   void do_something(typename boost::enable_if<typename T::condition>::type* = 0) {}
};

您也可以使用专业化,例如

template <bool> struct helper_do_something {};
template <> struct helper_do_something<true>
{
    void do_something() { /* Your implementation */ }
};

template <typename policy>
class test : helper_do_something<T::condition::value>
{
    // do_something is inherited (and it is present only when T::condition::value is true)
};