初始化模板特化的静态const

时间:2016-11-10 07:09:44

标签: c++ templates static-initialization

我创建了一个带有静态const元素的类模板。目的是使模板的每个特化都有自己的静态元素的版本/值。这是我的示例代码:

 import android.support.v4.app.Fragment;
 import org.androidannotations.annotations.*;
 import org.androidannotations.annotations.sharedpreferences.Pref;
.
.

@EFragment(R.layout.fragment_main)
public class MainFragment extends Fragment {
@Pref
ApplicationSettings_ applicationSettings;
@ViewById(R.id.bot)
public LinearLayout bot;
@ViewById(R.id.center)
public LinearLayout center;
@Bean
UIItemGenerator uiItemGenerator;
@SystemService
LayoutInflater layoutInflater;
@FragmentById(value = R.id.contentFragment,childFragment = true)
public ContentFragment contentFragment;

public MainFragment() {
}

@Click(R.id.imagebutton_ribbon)
public void ribbonClick(View view) {
    view.setVisibility(View.GONE);
}

.
.
.
@AfterViews
public void afterViews() {
    if (contentFragment == null)
        contentFragment = (ContentFragment) this.getChildFragmentManager().findFragmentById(R.id.contentFragment);
    for (int j = 0; j < bot.getChildCount(); j++) {
        bot.getChildAt(j).setSelected(false);
    }
    for (int j = 0; j < top.getChildCount(); j++) {
        top.getChildAt(j).setSelected(false);
    }
    ll_home.setSelected(true);
    ll_allrooms.setSelected(true);
    initUI();
    contentFragment.generateContent(-1, -1);
    imagebutton_top_rightarrow.setSelected(true);
    imagebutton_bot_rightarrow.setSelected(true);

使用可编译版本时,输出就是我所期望的:

template < typename T > class C
{
   public:
      static const std::string NAME;
      T something;
      void printName() { std::cout << NAME << std::endl; }
};

class C1 : public C< int >{};
class C2 : public C< char >{};

template<> const std::string C< int >::NAME{ "my int" };   // compiles
template<> const std::string C< char >::NAME{ "my char" }; // compiles

//template<> const std::string C1::NAME{ "my int" };   // doesn't compile
//template<> const std::string C2::NAME{ "my char" };  // doesn't compile

//const std::string C1::NAME{ "my int" };   // doesn't compile
//const std::string C2::NAME{ "my char" };  // doesn't compile

int main()
{
   C1 c1;
   C2 c2;

   c1.printName();
   c2.printName();

   std::cout << c1.NAME << "  " << c2.NAME << std::endl;
   std::cout << C1::NAME << "  " << C2::NAME << std::endl;
}

对于不编译的行,错误消息(使用gcc 4.4)表示

my int
my char
my int  my char
my int  my char

为什么不允许这样做?我的理解是模板的完全特化是所有(?)方面的类,并且该类具有在模板中声明的所有成员。所以我希望能够通过使用范围解析运算符来引用该类的静态成员。显然我可以在初始化之后这样做,就像在上面的主要的最后一行,但不是在初始化本身。

任何人都可以提供任何有关标准写入方式的见解吗?如果标准允许上面的'坏'语法,会出现什么样的问题?

1 个答案:

答案 0 :(得分:3)

在我看来,您遇到的问题与模板无关。问题是您尝试使用嵌套名称说明符中的派生类来定义静态成员,而不是原始类。你会遇到同样的问题:

struct A {
    static int x;
};
struct B : A{};
int B::x = 42;

代码中的C1C2不是C的完全特化,而是C的派生特化类。所以我不知道你在这里期待什么...