专门用于命名空间中的类的方法模板

Olu*_*ide 5 c++ templates sfinae

我正在使用以下编译时'技巧'(基于ADL)来创建一个仅由同一名称空间中的类有效/定义/可调用的函数.

    namespace Family1
    {
        struct ModelA{};
        struct ModelB{};

        template<typename T>
        bool is_in_Family1(T const& t) 
        {
            return true;
        }
    };

    namespace Family2
    {
        struct ModelC{};

        template<typename T>
        bool is_in_Family2(T const& t) 
        {
            return true;
        }
    };


    Family1::ModelA mA;
    Family2::ModelC mC;

    is_in_Family1(mA);          // VALID
    is_in_Family1(mC);          // ERROR
Run Code Online (Sandbox Code Playgroud)

现在,我想使用这个原则(或类似的东西),以便Foo::Bar为属于每个命名空间的类产生(下面)的特化(例如)Family1.

    // I would like to specialize the method template Bar for classes in Family1 
    // namespace; and another specialization for classes in Family2 namespace
    struct Foo
    {
        template<typename T>
        void Bar( T& _T ){}
    };
Run Code Online (Sandbox Code Playgroud)

为了便于维护和每个命名空间中的大量类,如果可能的话,我想在不命名命名空间中的所有类的情况下执行此检查.

Joe*_*oel 0

我发现做到这一点的最快方法是使用 Boost Type Traits' is_base_of<>

我尝试将继承与模板专业化结合使用,但这不起作用,因为使用模板专业化时会忽略继承,因此您必须专门针对每个模型。多个类的父类的部分特化的答案解释了这个问题。

如果您使 Family1::ModelA 和 Family::ModelB 成为 Family1:Family1Type 的子类,而 Family2::ModelC 成为 Family2::Family2Type 的子类,则使用类型特征有效:

#include <iostream>
#include <boost/type_traits/is_base_of.hpp>

namespace Family1{

    struct Family1Type{};

    struct ModelA :public Family1Type{};
    struct ModelB :public Family1Type{};

    template<typename T>
    bool is_in_Family1(const T& t){
        return boost::is_base_of<Family1::Family1Type,T>::value;
    }
};

namespace Family2{
    struct Family2Type{};

    struct ModelC :public Family2Type{};

    template<typename T>
    bool is_in_Family2(const T& t){
        return boost::is_base_of<Family2::Family2Type,T>::value;
    }

};

using namespace std;
int main(int argc, char *argv[]) {

    Family1::ModelA mA;
    Family2::ModelC mC;

    std::cout << "mA is in Family1?  " << is_in_Family1(mA) << std::endl;
    std::cout << "mC is in Family2?  " << is_in_Family2(mC) << std::endl;

    //std::cout << "mC is in Family1?  " << is_in_Family1(mC) << std::endl; //ERROR!
    //std::cout << "mA is in Family2?  " << is_in_Family2(mA) << std::endl; //ERROR!

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这会产生以下输出:

mA is in Family1?  1
mC is in Family2?  1
Run Code Online (Sandbox Code Playgroud)

我认为没有办法根据不同命名空间中的 'template<class _Tp> struct std::less' 的特化Foo来声明和专门化另一个命名空间Foo::Bar<>