【问题标题】:c++ How to initialize static variables of a partial template specializationc ++如何初始化部分模板特化的静态变量
【发布时间】:2012-11-15 19:26:30
【问题描述】:

我应该如何为偏特化初始化一个静态变量?

template <bool A=true, bool B=false>
struct from {
    const static std::string value; 
};

// no specialization - works
template <bool A, bool B>
const std::string from<A, B>::value = "";

// partial specialization - does not compile -  
// Error: template argument list following class template name must list parameters in the order used in template parameter list
// Error: from<A,B>' : too few template arguments
template <bool B>
const std::string from<true, B>::value = "";

// full specialization - works
const std::string from<false, true>::value = "";

为什么部分不起作用?

编辑:我找到了基于Partial template specialization for initialization of static data members of template classes的解决方案

在允许我初始化静态变量之前,我需要重复部分特化的声明:

template <bool B>
struct from<true, B> {
    const static std::string value; 
};

再次,问题是为什么?

【问题讨论】:

  • 哪个编译器?在g++ 4.3.4,最后一个也不起作用。
  • 你不需要专门化整个类模板吗?我认为成员只允许显式(=完全)专业化。

标签: c++ templates template-specialization


【解决方案1】:

如果没有封闭类模板本身的部分特化,则不允许成员的部分特化(无论它们是函数还是静态数据)。

也就是说,您还必须专门化类模板。所以以下应该工作:

//partial specialization of class template
template <bool B>
struct from<true, B> {
    const static std::string value; 
};

//now you can do this!    
template <bool B>
const std::string from<true, B>::value = ""

另外,这不会编译(你试过编译这个吗?):

// full specialization - works (SORRY, IT WILL NOT WORK!)
const std::string from<false, true>::value = "";  //this should be an error

你必须这样写:

// full specialization 
template<>   //<---- this is important!
const std::string from<false, true>::value = ""

【讨论】:

  • 好的。我的目标是用模板替换一些 if-the-else 语句。我发现在这种特定情况下使用静态变量是有问题的。您会推荐一种解决此问题的方法吗?我想根据模板参数值选择一个字符串。
  • @CandyChiu:为什么不使用字符串的数组/映射呢?或者你可以在类模板中使用成员函数,它会根据模板参数的值返回不同的值。
  • 我要编译时间选择。
  • @CandyChiu:为什么?在编译时你会用std::string 做什么?
  • 我要替换的代码是四个相似的类,但有几个字符串不同。模板似乎是将它们组合成 1 的不错选择。
【解决方案2】:

这是模板的完整专业化。

#include <string>
#include <iostream> 

template <bool A=true, bool B=false>
struct from {
  const static std::string value; 
};

// no specialization - works
template <bool A, bool B>
const std::string from<A, B>::value = "no specialization";

// full specialization, note the empty template parameter list
template <>
const std::string from<true, true>::value = "<true,true> specialization";


int main() {
   std::cout << from<false, false>::value << std::endl;
   std::cout << from<true, true>::value << std::endl;
}

您找到了定义部分的正确方法。

您的部分不起作用的原因是您需要先声明结构类型,然后才能为其静态字段提供初始化。部分特化本身就是一个模板,值得定义。

完全特化实际上是初始模板的类型实例,因此不需要单独定义。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-24
    • 2017-05-26
    • 1970-01-01
    • 1970-01-01
    • 2013-07-21
    • 1970-01-01
    相关资源
    最近更新 更多