C++ 模板结构 'has no member named' 错误

C++ template struct 'has no member named' error

T==BT==A 时,我可以在不对无成员 a 发出警告的情况下进行编译的唯一方法是在 if 语句块中 reinterpret_cast 和通过指针访问非共享成员。有没有办法解决这个问题或以其他方式提示编译器?

这是 gcc 4。8.x

enum Type { A, B};

template<Type T> struct S { };
template<> struct S<A> { int x; int a; };
template<> struct S<B> { int y; int x; int b; };

template<Type T> static void foo(int x)
{
    // lots of code

    S<T> s;
    s.x = someCall();

    if (T == A)
    {
        s.a = 1;
    }
    else if (T == B)
    {
        s.y = 2;
        s.b = 3;
    }

    // a bunch of common code
}

编辑:我知道制作一个专门的特定函数来处理细节,但我希望避免额外的样板代码。

您可以使用专业化:

template <Type T> void bar(S<T>&);

template <> void bar(S<A>& s) {s.a = 1;}
template <> void bar(S<B>& s) {s.y = 2; s.b = 3;}

template<Type T> static void foo(int x)
{
    // lots of code

    S<T> s;
    s.x = someCall();

    bar(s);

    // a bunch of common code
}
if (T == A)
[...]
else if (T == B)
[...]

ABT 这里是编译时实体,而不是 运行 时实体。然而,您正试图对编译时已知的事物执行 运行 时间评估。现在可以肯定的是,您可以尝试用一种不确定的转换(尝试,然后失败)来破解某些东西,或者尝试一些其他类型的笨拙,但代码告诉您:您做错了。

专业化 foo 是一种方式,利用 SFINAE 可能也是如此(与 enable_if 一样),但从我在这里看到的你的用例来看,这也是错误的做法.那是因为您要实现的代码是某种初始化代码,或者是操纵正在使用的对象的内部状态的代码。从某种意义上说,你违反了单一责任原则。

因此将该代码移至责任所属的位置:在 class 中 inited。

template<> struct S<A> { int x; int a; void init() {a=1;} };
template<> struct S<B> { int y; int x; int b; void init() { x=2; y=3; } };

template<Type T> static void foo(int x)
{
    // lots of code

    S<T> s;
    s.x = someCall();

    s.init();

    // a bunch of common code
}

您也可以使用工厂 class。这将抽象掉对象的实例化和对 init() 的调用,后者可以根据最终类型采用不同的参数。