如何解决结构对其他结构类型的循环依赖,定义在 header 只有库 (C++) 中?
How to solve circular dependency of structures to types of other structures, defined in a header only library (C++)?
我想写一个转换实用程序 header,它可以毫不费力地使用,所以它应该用作 header-only 库(因为它太小了,创建它会有点过分一个单独的 .lib 无论如何)。
这里是lib的草图(只包含UTF8和UTF16的转换)
namespace cp_utils {
namespace cp { //codepages
struct UTF8 {
typedef std::string string;
typedef const std::string& string_ref; //will be boost::string_ref later on
template<typename ToCP>
static typename ToCP::string convertTo(string_ref str);
template<>
static UTF16::string convertTo<UTF16>(string_ref str) { //<- Problem here!
//... convert UTF-8 string to UTF-16 wstring
return L"UTF-16"; //Mock implementation
}
};
struct UTF16 {
typedef std::wstring string;
typedef const std::wstring& string_ref;
template<typename ToCP>
static typename ToCP::string convertTo(string_ref str);
template<>
static UTF8::string convertTo<UTF8>(string_ref str) {
//... convert UTF-16 wstring to UTF-8 string
return "UTF-8"; //Mock implementation
}
};
///... other codepages similar
}
//actual conversion function
template<typename FromCP, typename ToCP>
inline typename ToCP::string convert(typename FromCP::string_ref str) {
return FromCP::convertTo<ToCP>(str);
}
}
//usage:
int main() {
wstring utf16str = convert<cp::UTF8, cp::UTF16>("test");
}
错误消息说 C2065:"UTF16" 未声明的标识符
我试图通过使用简单 struct UTF16;
的 UTF16 结构的前向声明来解决此问题,但随后出现错误状态 C2027:使用未定义类型 "UTF16"。在定义 UTF8 和 vice-versa.
之前,我必须以某种方式提供 UTF16 的完整定义
如果我在结构之外定义 UTF8 和 UTF16 的专用转换函数,那么只要库只在一个 .cpp 文件中使用它就可以正常工作,因为有多个定义,这使得这很不切实际。
我该如何解决这个问题?
PS: 我用MSVS 2013编译代码
转换函数不必是成员。如果你让它们成为自由函数,那么你就不必担心前向声明或循环引用。此外,您甚至不需要函数模板。只需将要转换的内容作为空类型参数传递即可:
struct UTF8 {
using string = std::string;
};
struct UTF16 {
using string = std::wstring;
};
// 8 --> 16
UTF16::string convertTo(UTF8::string const& from, UTF16 );
// 16 --> 8
UTF8::string convertTo(UTF16::string const& from, UTF8 );
用法如下:
UTF8::string some_string = ...;
auto as_utf_16 = convertTo(some_string, UTF16{});
这实际上是这个问题 Circular Dependencies / Incomplete Types 和一般 "how do I resolve circular dependencies in C / C++" 问题的副本,只是有点难看,因为涉及到模板。
基本上你应该移动这两个函数的实现
template<>
static UTF16::string convertTo<UTF16>(string_ref str) { //<- Problem here!
//... convert UTF-8 string to UTF-16 wstring
return L"UTF-16"; //Mock implementation
}
template<>
static UTF8::string convertTo<UTF8>(string_ref str) {
//... convert UTF-16 wstring to UTF-8 string
return "UTF-8"; //Mock implementation
}
在 class 个主体中,只留下声明,并将它们放在文件末尾。 (但仍在同一个命名空间中。)
我想写一个转换实用程序 header,它可以毫不费力地使用,所以它应该用作 header-only 库(因为它太小了,创建它会有点过分一个单独的 .lib 无论如何)。
这里是lib的草图(只包含UTF8和UTF16的转换)
namespace cp_utils {
namespace cp { //codepages
struct UTF8 {
typedef std::string string;
typedef const std::string& string_ref; //will be boost::string_ref later on
template<typename ToCP>
static typename ToCP::string convertTo(string_ref str);
template<>
static UTF16::string convertTo<UTF16>(string_ref str) { //<- Problem here!
//... convert UTF-8 string to UTF-16 wstring
return L"UTF-16"; //Mock implementation
}
};
struct UTF16 {
typedef std::wstring string;
typedef const std::wstring& string_ref;
template<typename ToCP>
static typename ToCP::string convertTo(string_ref str);
template<>
static UTF8::string convertTo<UTF8>(string_ref str) {
//... convert UTF-16 wstring to UTF-8 string
return "UTF-8"; //Mock implementation
}
};
///... other codepages similar
}
//actual conversion function
template<typename FromCP, typename ToCP>
inline typename ToCP::string convert(typename FromCP::string_ref str) {
return FromCP::convertTo<ToCP>(str);
}
}
//usage:
int main() {
wstring utf16str = convert<cp::UTF8, cp::UTF16>("test");
}
错误消息说 C2065:"UTF16" 未声明的标识符
我试图通过使用简单 struct UTF16;
的 UTF16 结构的前向声明来解决此问题,但随后出现错误状态 C2027:使用未定义类型 "UTF16"。在定义 UTF8 和 vice-versa.
如果我在结构之外定义 UTF8 和 UTF16 的专用转换函数,那么只要库只在一个 .cpp 文件中使用它就可以正常工作,因为有多个定义,这使得这很不切实际。
我该如何解决这个问题?
PS: 我用MSVS 2013编译代码
转换函数不必是成员。如果你让它们成为自由函数,那么你就不必担心前向声明或循环引用。此外,您甚至不需要函数模板。只需将要转换的内容作为空类型参数传递即可:
struct UTF8 {
using string = std::string;
};
struct UTF16 {
using string = std::wstring;
};
// 8 --> 16
UTF16::string convertTo(UTF8::string const& from, UTF16 );
// 16 --> 8
UTF8::string convertTo(UTF16::string const& from, UTF8 );
用法如下:
UTF8::string some_string = ...;
auto as_utf_16 = convertTo(some_string, UTF16{});
这实际上是这个问题 Circular Dependencies / Incomplete Types 和一般 "how do I resolve circular dependencies in C / C++" 问题的副本,只是有点难看,因为涉及到模板。
基本上你应该移动这两个函数的实现
template<>
static UTF16::string convertTo<UTF16>(string_ref str) { //<- Problem here!
//... convert UTF-8 string to UTF-16 wstring
return L"UTF-16"; //Mock implementation
}
template<>
static UTF8::string convertTo<UTF8>(string_ref str) {
//... convert UTF-16 wstring to UTF-8 string
return "UTF-8"; //Mock implementation
}
在 class 个主体中,只留下声明,并将它们放在文件末尾。 (但仍在同一个命名空间中。)