Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么不';是否允许在不同的名称空间中使用t模板专门化?_C++_Templates_Namespaces_Template Specialization - Fatal编程技术网

C++ 为什么不';是否允许在不同的名称空间中使用t模板专门化?

C++ 为什么不';是否允许在不同的名称空间中使用t模板专门化?,c++,templates,namespaces,template-specialization,C++,Templates,Namespaces,Template Specialization,请看我想做什么: #include <iostream> namespace first { template <class T> class myclass { T t; public: void who_are_you() const { std::cout << "first::myclass"; } }; } namespace second { using first::myclass; template <>

请看我想做什么:

#include <iostream>
namespace first
{
 template <class T>
 class myclass
 { 
  T t;
 public:
  void who_are_you() const
  { std::cout << "first::myclass"; }
 };
}
namespace second
{
 using first::myclass;
 template <>
 class myclass <int>
 {
  int i, j;
 public:
  void who_are_you() const
  { std::cout << "second::myclass"; }
 };
}

这能做到吗?

为什么会出现这样的问题?如果不了解,甚至很难开始回答它

专门化修改主模板。它不能以任何方式与主模板“分离”。在某种程度上,作为一个高级概念,它仍然是同一个模板(即使在较低级别,它被定义为一个独立的模板)。因此,出于明显的原因,它与主模板位于同一名称空间中

对不起,我无法提供更好的解释,因为我不明白这样的问题是如何产生的

顺便问一下,“在不同的命名空间中”是什么意思?您希望专门化是不同命名空间的成员吗?或者您希望在源代码中的不同名称空间中定义您的专门化,但仍然是原始名称空间的成员?

这会使事情变得复杂:

namespace first
{
  template <class T> class TArray;
}

namespace second
{
  using first::TArray;

  template <class U> class TArray < Node<U> >;
  //                              ^
  // Only there do you realize it's a specialization and not another template
}
名称空间优先
{
模板类焦油;
}
命名空间秒
{
使用第一:焦油;
模板类TArray;
//                              ^
//只有在那里,你才意识到这是一个专门化,而不是另一个模板
}
我理解你的挫败感,我也常常希望得到同样的东西。这似乎是绝对可能的,我当然不买逻辑分组的论点,但是我必须承认,它将需要更多的努力从编译器编写者,解析正确的C++已经是很困难的,因为它站立。

模板在C++中有点凌乱,如果你想知道我的观点,但是很容易用经验和使用20年来说明:

< P> C++ 2003,{7.4.3.1/1:“一个程序可以将任何标准库模板的模板特化添加到命名空间STD。这样的专门化(完整的或部分的)除非声明依赖于外部链接的用户定义名称,并且除非专门化满足原始模板的标准库要求,否则标准库模板的定义将导致未定义的行为。”

因此,您可以专门化库模板,并将专门化放在名称空间
std
,只要它取决于用户定义的类型并满足原始模板的要求

您在编辑的问题中的代码似乎是一个用户定义名称的专门化,该名称(可能)具有外部链接,因此您不应该对这部分内容有任何问题

这只剩下您的专业化满足原始模板要求的要求。对于您的类型,其中大部分可能都是琐碎的。我能看到的唯一不明显的部分是,您似乎必须为整个模板提供专门化,而不仅仅是
numeric\u limits::max()
。例如,您必须执行以下操作(128位无符号整数类型的示例应大致相同):

namespace std{
模板
类数值极限{
公众:
静态常量布尔值为_=true;
静态T min()throw(){返回0;
静态T max()throw(){return/*2^128-1*/;}//***
静态常量整数位数=128;
静态常数int digits10=38;
静态常量bool是有符号的=false;
静态常量bool为_整数=真;
静态常数布尔值为_精确=真;
静态常数int基数=2;
静态T epsilon()throw(){return 0;}
静态T round_error()throw(){return 0;}
静态常数int min_指数=0;
静态常数int min_指数10=0;
静态常数int max_指数=0;
静态常数int max_指数10=0;
静态常数布尔有_无穷大=假;
静态常量bool具有\u quiet\u NaN=false;
静态常量bool具有\u信令\u NaN=false;
静态常量float\u denorm\u样式具有\u denorm=denorm\u缺席;
静态常数bool有_denorm _loss=false;
静态T无穷大()throw(){return 0;}
静态T quiet_NaN()throw(){return 0;}
静态T信令_NaN()throw(){return 0;}
静态T denorm_min()throw(){return 0;}
静态常数布尔为_iec559=假;
静态常数布尔为有界=真;
静态常数布尔为_模=真;
静态常数陷阱=假;
静态常数bool tinyness_before=假;
静态常量浮动\u圆形\u样式圆形\u样式=朝向零的圆形\u;
};
}

其中有相当多的模板确实适用于FP类型,并且对于整数类型没有意义;我认为它们仍然需要实现。

作为替代方案,您不能创建一个从标准模板继承而来的新模板吗?根据§17.4.3.1/1:“程序可以将任何标准库模板的模板专门化添加到命名空间标准中。此类专门化(完整或部分)除非声明依赖于外部链接的用户定义名称,并且除非专门化满足原始模板的标准库要求,否则标准库模板的定义将导致未定义的行为。"因此,尽管存在限制,但在适当的情况下,您可以将此类专门化添加到
::std::
。@jerry Coffin我认为添加任何内容都会导致未定义的行为!请提供一个解释如何满足这些要求的答案?专门化模板不会向命名空间添加任何内容,因此永远无法实现有效的C++甚至建议专门化代码< STD::SWIFT < /C>。正如在C++ 11中所提到的,改变了关于模板实例化的文本。@ Matthew M.谢谢。好回答。这实际上是回答问题。谢谢你提供答案。请稍作澄清,什么是外部链接?如果我的LLibrary只是一个标题,行为是未定义的?否--“外部链接”主要是指它不是“静态”或在匿名命名空间中。未命名命名空间中的内容仍然具有外部链接。
namespace first
{
  template <class T> class TArray;
}

namespace second
{
  using first::TArray;

  template <class U> class TArray < Node<U> >;
  //                              ^
  // Only there do you realize it's a specialization and not another template
}
namespace std { 
template <>
class numeric_limits<my_integer> {
public:

    static const bool is_specialized = true;
    static T min() throw() { return 0;
    static T max() throw() { return /* 2^128-1 */; } // ***
    static const int digits = 128;
    static const int digits10 = 38;
    static const bool is_signed = false;
    static const bool is_integer = true;
    static const bool is_exact = true;
    static const int radix = 2;
    static T epsilon() throw() { return 0; }
    static T round_error() throw() { return 0; }
    static const int min_exponent = 0;
    static const int min_exponent10 = 0;
    static const int max_exponent = 0;
    static const int max_exponent10 = 0;
    static const bool has_infinity = false;
    static const bool has_quiet_NaN = false;
    static const bool has_signaling_NaN = false;
    static const float_denorm_style has_denorm = denorm_absent;
    static const bool has_denorm_loss = false;
    static T infinity() throw() { return 0; }
    static T quiet_NaN() throw() { return 0; }
    static T signaling_NaN() throw() { return 0; }
    static T denorm_min() throw() { return 0; }
    static const bool is_iec559 = false;
    static const bool is_bounded = true;
    static const bool is_modulo = true;
    static const bool traps = false;
    static const bool tinyness_before = false;
    static const float_round_style round_style = round_toward_zero;
};
}