C++ 专门化嵌套类';静态函数导致编译器错误C3855(MSVC9)

C++ 专门化嵌套类';静态函数导致编译器错误C3855(MSVC9),c++,visual-studio-2008,C++,Visual Studio 2008,这是本书的延续 我试图用嵌套类模板创建一个类模板,其中嵌套类模板有一个静态函数,我想为其提供专门化 这是我的测试代码,它不提供嵌套类的专门化。注意存在空类NullType——这就是我想要专门化嵌套类的地方 #include <cstdlib> #include <iostream> using namespace std; class NullType {}; template<class FooParam> struct Foo { templa

这是本书的延续

我试图用嵌套类模板创建一个类模板,其中嵌套类模板有一个静态函数,我想为其提供专门化

这是我的测试代码,它不提供嵌套类的专门化。注意存在空类
NullType
——这就是我想要专门化嵌套类的地方

#include <cstdlib>
#include <iostream>
using namespace std;

class NullType {};

template<class FooParam> struct Foo
{
    template<class BarParam> struct Bar
    {
        static bool Magic();
    };
};

template<class FooParam> 
template<class BarParam> 
bool Foo<FooParam>::Bar<BarParam>::Magic()
{
    return true;
}

int main()
{
    bool b = Foo<int>::Bar<int>::Magic();
    cout << b << " ";
    bool b2 = Foo<int>::Bar<NullType>::Magic();
    cout << b2 << " ";

}
现在我想在
NullType
上提供一个专门化的
Bar::Magic
,并让该函数返回
false
。所需输出为:

1 1
1 0
所以我试着这样写专业化:

template<class FooParam>
template<>
bool Foo<FooParam>::Bar<NullType>::Magic()
{
    return false;
} // COMPILER ERROR HERE C3855
…在上述闭合支架上

我可以使用什么语法来提供这种专门化?我愿意使用任何和所有技术来实现我的主要目标(对于
NullType
返回
false
,对于其他所有内容返回
true
),只要:

  • 没有使用外部库(没有Boost)
  • 使用符合C++的仅
  • Foo
    是类模板,
    Bar
    是嵌套类模板或函数模板。返回
    false
    true
    的函数必须可以专门化或重载,以便调用
    NullType
    的代码返回
    false
    ,但其他所有函数都将返回
    true

  • <>我将澄清需求。

    < P>快速解决方案是使用Type ID操作符,即标准C++(5.2.8)。因此,Magic()函数的内容如下:

    template<class FooParam> 
    template<class BarParam> 
    bool Foo<FooParam>::Bar<BarParam>::Magic()
    {
        if (typeid(BarParam) == typeid(NullType))
            return false;
    
        return true;
    }
    
    模板
    模板
    bool Foo::Bar::Magic()
    {
    if(typeid(BarParam)=typeid(NullType))
    返回false;
    返回true;
    }
    

    据我所知,编译器在实际实现typeid和typeinfo时有一定的自由度,但是==操作符保证像您期望的那样工作。需要注意的是,显然有些编译器出于性能考虑默认不支持运行时类型信息;大多数应该有一个标志来打开它。

    < P>快速的解决方案是使用Type ID操作符,这是标准C++(5.2.8)。因此,Magic()函数的内容如下:

    template<class FooParam> 
    template<class BarParam> 
    bool Foo<FooParam>::Bar<BarParam>::Magic()
    {
        if (typeid(BarParam) == typeid(NullType))
            return false;
    
        return true;
    }
    
    模板
    模板
    bool Foo::Bar::Magic()
    {
    if(typeid(BarParam)=typeid(NullType))
    返回false;
    返回true;
    }
    

    据我所知,编译器在实际实现typeid和typeinfo时有一定的自由度,但是==操作符保证像您期望的那样工作。需要注意的是,显然有些编译器出于性能考虑默认不支持运行时类型信息;不过,大多数都应该有一个标志来打开它。

    C++03和C++11都禁止专门化嵌套类/方法而不专门化其封闭类,如@Ise Wisteria的评论中所述

    以下使用重载的解决方案对您有效吗

    #include <cstdlib>
    #include <iostream>
    using namespace std;
    
    class NullType {};
    
    template<class FooParam> struct Foo
    {
        template<class BarParam> static bool Magic(BarParam);
        static bool Magic(NullType);
    };
    
    template<class FooParam> 
    template<class BarParam> 
    bool Foo<FooParam>::Magic(BarParam)
    {
        return true;
    }
    
    template<class FooParam> 
    bool Foo<FooParam>::Magic(NullType)
    {
        return false;
    }
    
    int main()
    {
        bool b = Foo<int>::Magic(int());
        cout << b << " ";
        bool b2 = Foo<int>::Magic(NullType());
        cout << b2 << " ";
    }
    
    #包括
    #包括
    使用名称空间std;
    类NullType{};
    模板结构Foo
    {
    模板静态布尔魔法(BarParam);
    静态布尔魔法(NullType);
    };
    模板
    模板
    bool-Foo::Magic(BarParam)
    {
    返回true;
    }
    模板
    bool-Foo::Magic(NullType)
    {
    返回false;
    }
    int main()
    {
    bool b=Foo::Magic(int());
    
    coutC++03和C++11都禁止专门化嵌套类/方法而不专门化其封闭类,如@Ise Wisteria的评论中所述

    以下使用重载的解决方案对您有效吗

    #include <cstdlib>
    #include <iostream>
    using namespace std;
    
    class NullType {};
    
    template<class FooParam> struct Foo
    {
        template<class BarParam> static bool Magic(BarParam);
        static bool Magic(NullType);
    };
    
    template<class FooParam> 
    template<class BarParam> 
    bool Foo<FooParam>::Magic(BarParam)
    {
        return true;
    }
    
    template<class FooParam> 
    bool Foo<FooParam>::Magic(NullType)
    {
        return false;
    }
    
    int main()
    {
        bool b = Foo<int>::Magic(int());
        cout << b << " ";
        bool b2 = Foo<int>::Magic(NullType());
        cout << b2 << " ";
    }
    
    #包括
    #包括
    使用名称空间std;
    类NullType{};
    模板结构Foo
    {
    模板静态布尔魔法(BarParam);
    静态布尔魔法(NullType);
    };
    模板
    模板
    bool-Foo::Magic(BarParam)
    {
    返回true;
    }
    模板
    bool-Foo::Magic(NullType)
    {
    返回false;
    }
    int main()
    {
    bool b=Foo::Magic(int());
    
    cout另一种变体是使用非嵌套特征类:

    class NullType {};
    
    template<class FooParam> struct Foo
    {
        template<class BarParam> struct Bar
        {
            static bool Magic();
        };
    };
    
    template<class T> struct bool_trait
    {
        static const bool value = true;
    };
    
    template<> struct bool_trait<NullType>
    {
        static const bool value = false;
    };
    
    template<class FooParam> 
    template<class BarParam> 
    bool Foo<FooParam>::Bar<BarParam>::Magic()
    {
        return bool_trait<BarParam>::value;
    }
    
    类空类型{};
    模板结构Foo
    {
    模板结构栏
    {
    静态布尔魔法();
    };
    };
    模板结构bool\u特征
    {
    静态常量布尔值=真;
    };
    模板结构bool\u特征
    {
    静态常量布尔值=假;
    };
    模板
    模板
    bool Foo::Bar::Magic()
    {
    返回bool_trait::value;
    }
    
    另一种替代方法是使用非嵌套特征类:

    class NullType {};
    
    template<class FooParam> struct Foo
    {
        template<class BarParam> struct Bar
        {
            static bool Magic();
        };
    };
    
    template<class T> struct bool_trait
    {
        static const bool value = true;
    };
    
    template<> struct bool_trait<NullType>
    {
        static const bool value = false;
    };
    
    template<class FooParam> 
    template<class BarParam> 
    bool Foo<FooParam>::Bar<BarParam>::Magic()
    {
        return bool_trait<BarParam>::value;
    }
    
    类空类型{};
    模板结构Foo
    {
    模板结构栏
    {
    静态布尔魔法();
    };
    };
    模板结构bool\u特征
    {
    静态常量布尔值=真;
    };
    模板结构bool\u特征
    {
    静态常量布尔值=假;
    };
    模板
    模板
    bool Foo::Bar::Magic()
    {
    返回bool_trait::value;
    }
    
    根据14.7.3/18,成员模板在其封闭类模板被专门化之前不能被专门化。因此,您的要求可能无法按原样得到满足……根据14.7.3/18,成员模板在其封闭类模板被专门化之前不能被专门化。因此,您的要求可能无法被满足尽管如此。。。