首页 文章

部分模板专业化使用不完整类型无效c

提问于
浏览
2

我正在尝试专门化一个类方法 foo() . 这适用于完整的模板专业化 . 但是,这不适用于部分模板专业化 .

这里是在GCC和Clang上编译好的示例代码:

#include <iostream>
#include <string>

template <typename Key, typename Value>
struct SimpleKey {
    Key   key;
    Value value;
    void foo() const { 
        std::cout << "base" << std::endl; 
    }
};

/*
// Uncomment this and it won't work !
template<typename Key>
void SimpleKey<Key, std::string>::foo() const {
    std::cout << "partial" << std::endl; 
}
*/

template<>
void SimpleKey<int, std::string>::foo() const {
    std::cout << "full" << std::endl; 
}


int main() {
    SimpleKey<double, std::string> key1{1.0,"key1"};
    key1.foo();
    SimpleKey<int, std::string> key2{1,"key2"};
    key2.foo();
}

取消注释相关代码时我得到的Clang和GCC错误是:

错误:无效使用不完整类型'struct SimpleKey>'void SimpleKey :: foo()const {

我应该怎么做才能让部分模板专业化与“最小化”工作正常工作?

2 回答

  • 0

    您可以显式地专门化类模板的特定隐式实例化的成员函数 . 但部分专业化不允许这样做 . 如果您不想编写完整的部分特化,可以考虑使用标记调度:

    private:
    void foo(std::true_type /*value_is_string*/) const { /* "partial" */ }
    void foo(std::false_type /*value_is_string*/) const { /* "base" */ }
    
    public:
    void foo() const { return foo(std::is_same<Value, std::string>()); }
    

    或者将 foo() 重构为您部分专门化的基类模板 .

  • 2

    这是不可能直接的 . (这很遗憾,这种语法很好)但你可以这样做:

    namespace detail {
        inline void f_(int i) { /* spé for int */}
        inline void f_(long i) { /* spé for long*/}
        /* other spe... */
    }
    
    template<class T>
    struct Foo{
        void f(T arg) { detail::f_(arg);}
    };
    

    它不是那么直接,但它仍然易于阅读 .

相关问题