免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2755 | 回复: 4
打印 上一主题 下一主题

[C++] 【求助】模板实例化时选择特化版本的问题 [复制链接]

论坛徽章:
7
酉鸡
日期:2013-10-30 17:17:51水瓶座
日期:2014-01-25 14:47:21天秤座
日期:2014-02-20 09:49:50处女座
日期:2014-11-04 17:44:082015年亚洲杯之中国
日期:2015-03-09 17:21:312015亚冠之北京国安
日期:2015-06-01 16:58:552015亚冠之山东鲁能
日期:2015-06-19 11:30:08
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-02-08 16:22 |只看该作者 |倒序浏览
  1. //
  2. // Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // (See accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. //

  7. #ifndef SOCI_USE_TYPE_H_INCLUDED
  8. #define SOCI_USE_TYPE_H_INCLUDED

  9. #include "soci-backend.h"
  10. #include "type-ptr.h"
  11. #include "exchange-traits.h"

  12. #include <string>
  13. #include <vector>

  14. namespace soci
  15. {

  16. namespace details
  17. {

  18. class statement_impl;

  19. // this is intended to be a base class for all classes that deal with
  20. // binding input data (and OUT PL/SQL variables)
  21. class SOCI_DECL use_type_base
  22. {
  23. public:
  24.     virtual ~use_type_base() {}

  25.     virtual void bind(statement_impl & st, int & position) = 0;
  26.     virtual void pre_use() = 0;
  27.     virtual void post_use(bool gotData) = 0;
  28.     virtual void clean_up() = 0;

  29.     virtual std::size_t size() const = 0;  // returns the number of elements
  30. };

  31. typedef type_ptr<use_type_base> use_type_ptr;

  32. class SOCI_DECL standard_use_type : public use_type_base
  33. {
  34. public:
  35.     standard_use_type(void * data, exchange_type type,
  36.         bool readOnly, std::string const & name = std::string())
  37.         : data_(data), type_(type), ind_(NULL),
  38.         readOnly_(readOnly), name_(name), backEnd_(NULL) {}
  39.     standard_use_type(void * data, exchange_type type, indicator & ind,
  40.         bool readOnly, std::string const & name = std::string())
  41.         : data_(data), type_(type), ind_(&ind),
  42.         readOnly_(readOnly), name_(name), backEnd_(NULL) {}

  43.     virtual ~standard_use_type();
  44.     virtual void bind(statement_impl & st, int & position);
  45.     std::string get_name() const {return name_;}
  46.     virtual void * get_data() {return data_;}

  47.     // conversion hook (from arbitrary user type to base type)
  48.     virtual void convert_to_base() {}
  49.     virtual void convert_from_base() {}

  50. protected:
  51.     virtual void pre_use();

  52. private:
  53.     virtual void post_use(bool gotData);
  54.     virtual void clean_up();
  55.     virtual std::size_t size() const { return 1; }

  56.     void * data_;
  57.     exchange_type type_;
  58.     indicator * ind_;
  59.     bool readOnly_;
  60.     std::string name_;

  61.     standard_use_type_backend * backEnd_;
  62. };

  63. class SOCI_DECL vector_use_type : public use_type_base
  64. {
  65. public:
  66.     vector_use_type(void * data, exchange_type type,
  67.         std::string const & name = std::string())
  68.         : data_(data), type_(type), ind_(NULL),
  69.         name_(name), backEnd_(NULL) {}

  70.     vector_use_type(void * data, exchange_type type,
  71.         std::vector<indicator> const & ind,
  72.         std::string const & name = std::string())
  73.         : data_(data), type_(type), ind_(&ind),
  74.         name_(name), backEnd_(NULL) {}

  75.     ~vector_use_type();

  76. private:
  77.     virtual void bind(statement_impl & st, int & position);
  78.     virtual void pre_use();
  79.     virtual void post_use(bool) { /* nothing to do */ }
  80.     virtual void clean_up();
  81.     virtual std::size_t size() const;

  82.     void * data_;
  83.     exchange_type type_;
  84.     std::vector<indicator> const * ind_;
  85.     std::string name_;

  86.     vector_use_type_backend * backEnd_;

  87.     virtual void convert_to_base() {}
  88. };

  89. // implementation for the basic types (those which are supported by the library
  90. // out of the box without user-provided conversions)

  91. template <typename T>
  92. class use_type : public standard_use_type
  93. {
  94. public:
  95.     use_type(T & t, std::string const & name = std::string())
  96.         : standard_use_type(&t,
  97.             static_cast<exchange_type>(exchange_traits<T>::x_type),
  98.             false, name) {}
  99.     use_type(T const & t, std::string const & name = std::string())
  100.         : standard_use_type(const_cast<T *>(&t),
  101.             static_cast<exchange_type>(exchange_traits<T>::x_type),
  102.             true, name) {}
  103.     use_type(T & t, indicator & ind,
  104.         std::string const & name = std::string())
  105.         : standard_use_type(&t,
  106.             static_cast<exchange_type>(exchange_traits<T>::x_type),
  107.             ind, false, name) {}
  108.     use_type(T const & t, indicator & ind,
  109.         std::string const & name = std::string())
  110.         : standard_use_type(const_cast<T *>(&t),
  111.             static_cast<exchange_type>(exchange_traits<T>::x_type),
  112.             ind, false, name) {}
  113. };

  114. // special cases for char* and char[]

  115. template <>
  116. class use_type<char *> : public standard_use_type
  117. {
  118. public:
  119.     use_type(char * str, std::size_t bufSize,
  120.         std::string const & name = std::string())
  121.         : standard_use_type(&str_, x_cstring, false, name), str_(str, bufSize) {}
  122.     use_type(char const * str, std::size_t bufSize,
  123.         std::string const & name = std::string())
  124.         : standard_use_type(&str_, x_cstring, true, name),
  125.         str_(const_cast<char *>(str), bufSize) {}
  126.     use_type(char * str, indicator & ind, std::size_t bufSize,
  127.         std::string const & name = std::string())
  128.         : standard_use_type(&str_, x_cstring, ind, false, name), str_(str, bufSize) {}
  129.     use_type(char const * str, indicator & ind, std::size_t bufSize,
  130.         std::string const & name = std::string())
  131.         : standard_use_type(&str_, x_cstring, ind, true, name),
  132.         str_(const_cast<char *>(str), bufSize) {}

  133. private:
  134.     cstring_descriptor str_;
  135. };

  136. template <std::size_t N>
  137. class use_type<char[N]> : public use_type<char *>
  138. {
  139. public:
  140.     use_type(char str[], std::string const & name = std::string())
  141.         : use_type<char *>(str, N, name) {}
  142.     use_type(char const str[], std::string const & name = std::string())
  143.         : use_type<char *>(str, N, name) {}
  144.     use_type(char str[], indicator & ind,
  145.         std::string const & name = std::string())
  146.         : use_type<char *>(str, ind, N, name) {}
  147.     use_type(char const str[], indicator & ind,
  148.         std::string const & name = std::string())
  149.         : use_type<char *>(str, ind, N, name) {}
  150. };

  151. template <std::size_t N>
  152. class use_type<const char[N]> : public use_type<char *>
  153. {
  154. public:
  155.     use_type(char str[], std::string const & name = std::string())
  156.         : use_type<char *>(str, N, name) {}
  157.     use_type(char const str[], std::string const & name = std::string())
  158.         : use_type<char *>(str, N, name) {}
  159.     use_type(char str[], indicator & ind,
  160.         std::string const & name = std::string())
  161.         : use_type<char *>(str, ind, N, name) {}
  162.     use_type(char const str[], indicator & ind,
  163.         std::string const & name = std::string())
  164.         : use_type<char *>(str, ind, N, name) {}
  165. };

  166. // helper dispatchers for basic types

  167. template <typename T>
  168. use_type_ptr do_use(T & t, std::string const & name, basic_type_tag)
  169. {
  170.     return use_type_ptr(new use_type<T>(t, name));
  171. }

  172. template <typename T>
  173. use_type_ptr do_use(T const & t, std::string const & name, basic_type_tag)
  174. {
  175.     return use_type_ptr(new use_type<T>(t, name));
  176. }

  177. template <typename T>
  178. details::use_type_ptr use(T & t, std::string const & name = std::string())
  179. {
  180.     return details::do_use(t, name,
  181.         typename details::exchange_traits<T>::type_family());
  182. }

  183. template <typename T>
  184. details::use_type_ptr use(T const & t, std::string const & name = std::string())
  185. {
  186.     return details::do_use(t, name,
  187.         typename details::exchange_traits<T>::type_family());
  188. }

  189. } // namespace details

  190. } // namesapce soci

  191. #endif // SOCI_USE_TYPE_H_INCLUDED
复制代码
相关代码如上,如果我定义变量const char s[] = "Hello,CONST",并且调用use(s)或者use<const char[sizeof(s)]>(s)时,AIX的xlC编译器并不会选择特化的use_type<char[N]>或者use_type<const char[N]>,而是选择了最基本的use_type(即118行的版本),但是exchange_traits<char[N]>并没有声明x_type,造成编译错误(并且也违反了设计的思路)。
但是如果我调用use<char[sizeof(s)]>(s),xlC却会选择use_type<char[N]>特化版本,能够正确编译,生成的代码测试也正常。
请问为什么调用use(s)或者use<const char[sizeof(s)]>(s)时,xlC为什么不选择use_type<const char[N]>呢?如何让他选择use_type<const char[N]>呢?
谢谢!!

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
2 [报告]
发表于 2010-02-08 22:08 |只看该作者
看不懂……  而且没有xlC …… xlC是哪个平台的编译器?

重载解析我一直没搞懂过……   要不你试试把无关代码都删除, 看看
use -> do_use ->  这个调用链上的T分别被解析为什么类型

然后再看采取什么方法让use 解析为你需要的类型……

论坛徽章:
7
酉鸡
日期:2013-10-30 17:17:51水瓶座
日期:2014-01-25 14:47:21天秤座
日期:2014-02-20 09:49:50处女座
日期:2014-11-04 17:44:082015年亚洲杯之中国
日期:2015-03-09 17:21:312015亚冠之北京国安
日期:2015-06-01 16:58:552015亚冠之山东鲁能
日期:2015-06-19 11:30:08
3 [报告]
发表于 2010-02-09 09:06 |只看该作者
xlC是IBM AIX上的编译器,T被解析成const char [13],下面是具体的报错信息:
  1. "../../../core/exchange-traits.h", line 36.9: 1540-0130 (S) "exchange_traits<const char [13]>::x_type" is not declared.
  2. "../../../core/use.h", line 33.27: 1540-0700 (I) The previous message was produced while processing "struct soci::details::exchange_traits<const char [13]>".
  3. "../../../core/type-conversion.h", line 80.5: 1540-0401 (S) The member "soci::details::conversion_use_type<const char [13]>::conversion_use_type(const char [13] &, const std::string &)" is already declared.
  4. "../../../core/type-conversion.h", line 76.5: 1540-0425 (I) "conversion_use_type" is defined on line 76 of "../../../core/type-conversion.h".
  5. "../../../core/type-conversion.h", line 274.25: 1540-0700 (I) The previous message was produced while processing "class soci::details::conversion_use_type<const char [13]>".
复制代码

论坛徽章:
0
4 [报告]
发表于 2010-06-02 17:18 |只看该作者
vc2005 编译的时候一样有这个错误

论坛徽章:
0
5 [报告]
发表于 2010-06-02 18:27 |只看该作者
如果某个语法特性不被大多数编译器支持,稳妥的方案就是不要用它。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP