首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何解决结构与其他结构类型之间的循环依赖关系,这些结构是在标头专用库(C++)中定义的?

如何解决结构与其他结构类型之间的循环依赖关系,这些结构是在标头专用库(C++)中定义的?
EN

Stack Overflow用户
提问于 2015-08-31 18:00:51
回答 2查看 117关注 0票数 2

我想编写一个转换实用程序头,它可以不费吹灰之力地使用,所以它应该被用作一个只有头的库(因为它太小了,所以无论如何为它创建一个独立的.lib都太过分了)。

下面是库的草图(只包含UTF8和UTF16转换)

代码语言:javascript
运行
复制
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”。在定义UTF16之前,我必须提供UTF8的完整定义,反之亦然。

如果我在结构之外定义了UTF8和UTF16的专用转换函数,那么只要库由于多个定义而只在一个.cpp文件中使用,它就能正常工作,这使得这非常不切实际。

我该如何解决这个问题?

PS:我用MSVS 2013编译了代码

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-08-31 18:08:41

这实际上是一个重复的问题Circular Dependencies / Incomplete Types和一般的“我如何解决C/C++中的循环依赖”问题,它只是有点难看,因为其中涉及模板。

基本上,您应该移动这两个函数的实现。

代码语言:javascript
运行
复制
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
 }

离开类主体,只留下声明,并将这些声明放在文件的末尾。(但仍然在同一个名称空间中。)

票数 4
EN

Stack Overflow用户

发布于 2015-08-31 18:08:33

转换函数不必是成员。如果您使它们成为自由函数,那么您就不必担心前向声明或循环引用。此外,您甚至不需要有函数模板。只需将要转换的内容作为空类型参数传递:

代码语言:javascript
运行
复制
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 );

用法就像:

代码语言:javascript
运行
复制
UTF8::string some_string = ...;
auto as_utf_16 = convertTo(some_string, UTF16{});
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32317165

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档