C++ 的问题部分模板专业化

发布于 2024-11-19 20:30:40 字数 1147 浏览 3 评论 0原文

我有一个与此类似的情况:

template<class A, class B>
class MyClass<A, B>
{
  ...
  static A RARELY_USED_A;
}

// Seems to work but does not cover all possible cases, since 
// there may be instances of A that have no numeric limits.
template<class A, class B>
A MyClass<A, B>::RARELY_USED_A= std::numeric_limits<A>::max();

从我所看到的来看,这似乎可行。但是,在某些情况下,字符串可能会用作 A,因此我想我只需为这种特殊情况创建一个专门化即可。

// Does not complile
template<class B>
string MyClass<string, B>::RARELY_USED_A= "";

不幸的是,这不能正确遵守错误消息:

error: template definition of non-template 'std::string MyClass<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, B>::RARELY_USED_A'

请注意,另一方面,完整的专业化似乎可以工作(在运行时未经测试但可以编译)

// This complies but is not gernic enough and hence useless to me
template<>
string MyClass<string, string>::RARELY_USED_A= "";

我认为,我一定做错了什么。如果您能指出它到底是什么,我将非常感激。我认为部分专业化应该以这种方式进行。

预先非常感谢。

e:将 DEFAULT_A 的名称编辑为 RARELY_USED_A,因为我认为“默认”在某种程度上具有误导性

I have a situation similar to this:

template<class A, class B>
class MyClass<A, B>
{
  ...
  static A RARELY_USED_A;
}

// Seems to work but does not cover all possible cases, since 
// there may be instances of A that have no numeric limits.
template<class A, class B>
A MyClass<A, B>::RARELY_USED_A= std::numeric_limits<A>::max();

From what I saw this seems to work. However, strings may be used as A under some circumstances and so I thought I'd simply create a specialization for this special case.

// Does not complile
template<class B>
string MyClass<string, B>::RARELY_USED_A= "";

unfortunately this does not complie properly with error msg:

error: template definition of non-template 'std::string MyClass<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, B>::RARELY_USED_A'

Note that, on the othre hand, a full specialization seems to work (untested at runtime but compiles)

// This complies but is not gernic enough and hence useless to me
template<>
string MyClass<string, string>::RARELY_USED_A= "";

I assume, I must be doing something wrong. I would be really grateful if you could point out what exactly it is. I thought partical specializations were supposed to work this way.

Thanks a lot in advance.

e: edited the name of the DEFAULT_A to RARELY_USED_A, because I thought that "default" was misleading somehow

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

抠脚大汉 2024-11-26 20:30:41

使用继承来重用和专门化,而无需复制所有公共代码:

template<typename A>
struct RarelyUsedShared
{
    static A RARELY_USED_A;
};

template<typename A>
A RarelyUsedShared<A>::RARELY_USED_A = std::numeric_limits<A>::max();

template<>
string RarelyUsedShared<string>::RARELY_USED_A = "";

template<typename A, typename B>
class MyClass<A, B> : RarelyUsedShared<A>
{
  ...
};

请注意,这将导致在各种 B 之间共享该成员,如果该成员应该是 const,那么这是可以的。如果没有,助手可以采用两个模板参数,并且您可以部分特化它:

template<typename A, typename B>
struct RarelyUsedNotShared
{
    static A RARELY_USED_A;
};

template<typename A, typename B>
A RarelyUsedNotShared<A, B>::RARELY_USED_A = std::numeric_limits<A>::max();

template<typename B>
struct RarelyUsedNotShared<string, B>
{
    static A RARELY_USED_A;
};

typename<typename B>
string RarelyUsedNotShared<string, B>::RARELY_USED_A = "";

template<typename A, typename B>
class MyClass<A, B> : RarelyUsedNotShared<A, B>
{
  ...
};

Use inheritance to reuse and specialize without duplicating all the common code:

template<typename A>
struct RarelyUsedShared
{
    static A RARELY_USED_A;
};

template<typename A>
A RarelyUsedShared<A>::RARELY_USED_A = std::numeric_limits<A>::max();

template<>
string RarelyUsedShared<string>::RARELY_USED_A = "";

template<typename A, typename B>
class MyClass<A, B> : RarelyUsedShared<A>
{
  ...
};

Note that this will result in sharing the member across various B, which is ok if the member should be const. If not, the helper can take two template parameters, and you can partially specialize it:

template<typename A, typename B>
struct RarelyUsedNotShared
{
    static A RARELY_USED_A;
};

template<typename A, typename B>
A RarelyUsedNotShared<A, B>::RARELY_USED_A = std::numeric_limits<A>::max();

template<typename B>
struct RarelyUsedNotShared<string, B>
{
    static A RARELY_USED_A;
};

typename<typename B>
string RarelyUsedNotShared<string, B>::RARELY_USED_A = "";

template<typename A, typename B>
class MyClass<A, B> : RarelyUsedNotShared<A, B>
{
  ...
};
爱,才寂寞 2024-11-26 20:30:41

您需要为整个班级提供部分专业化,而不仅仅是单个成员。

You need to give a partial specialization to your entire class, not just a single member.

勿忘心安 2024-11-26 20:30:41

如果您的 RARELY_USED 是 const,您可以使用一个小帮助器类:

template <class A, class B>
const A MyClass<A, B>::RARELY_USED_A = Helper<A>::value;

/*...*/

#include <limits>
#include <string>

template <typename A> struct Helper { static const A RARELY_USED_A; };
template <typename A> const A Helper<A>::RARELY_USED_A = std::numeric_limits<A>::max();

template <> struct Helper<std::string> { static const std::string RARELY_USED_A; };
const std::string Helper<std::string>::RARELY_USED_A = "";

If your RARELY_USED is const, you could use a little helper class:

template <class A, class B>
const A MyClass<A, B>::RARELY_USED_A = Helper<A>::value;

/*...*/

#include <limits>
#include <string>

template <typename A> struct Helper { static const A RARELY_USED_A; };
template <typename A> const A Helper<A>::RARELY_USED_A = std::numeric_limits<A>::max();

template <> struct Helper<std::string> { static const std::string RARELY_USED_A; };
const std::string Helper<std::string>::RARELY_USED_A = "";
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文