部分模板专业化 c++ 的不完整类型无效使用
Invalid use of incomplete type for partial template specialization c++
我正在尝试专门化 class 方法 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 的错误是:
error: invalid use of incomplete type ‘struct SimpleKey >’ void SimpleKey::foo() const {
我应该怎么做才能使部分模板专业化在 "minimal" 的努力下正常工作?
直接是不可能的。 (很遗憾,这种语法很好)
但是你可以这样做:
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);}
};
它不是那么直接,但仍然易于阅读。
您可以显式特化 class 模板的特定隐式实例化的成员函数。但这对于部分专业化是不允许的。如果不想写全偏特化,可以考虑使用tag dispatch:
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()
重构为您部分专门化的基础 class 模板。
我正在尝试专门化 class 方法 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 的错误是:
error: invalid use of incomplete type ‘struct SimpleKey >’ void SimpleKey::foo() const {
我应该怎么做才能使部分模板专业化在 "minimal" 的努力下正常工作?
直接是不可能的。 (很遗憾,这种语法很好) 但是你可以这样做:
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);}
};
它不是那么直接,但仍然易于阅读。
您可以显式特化 class 模板的特定隐式实例化的成员函数。但这对于部分专业化是不允许的。如果不想写全偏特化,可以考虑使用tag dispatch:
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()
重构为您部分专门化的基础 class 模板。