1

我需要访问static constexpr一个我放在一起的解决方案,它适用于 gcc(现场示例),但不适用于 vc++(现场示例)。

代码如下:

template<class Drvd>
class Base
{
public:
    static constexpr bool val = Drvd::val;
};

class Derived : public Base<Derived>
{
    friend class Base;
private:
    static constexpr bool val = true;
};

int main()
{
    std::cout << Derived::Base::val << std::endl;
}

所以这是 vc++ 的一个错误,但是任何人都知道如何以vc++ 不会抱怨的不同方式将inval定义为 in的Base值?valDrvd

编辑: 请注意,结果与变体相同:friend class Base<Derived>;而不是friend class Base;

4

3 回答 3

1

您可以使用一种方法:

#include <iostream>

template<class Drvd>
class Base
{
public:
    static constexpr bool val() { return Drvd::val;  }
};

class Derived : public Base<Derived>
{
    friend class Base<Derived>;
private:
    static constexpr bool val = true;
};

int main()
{
    std::cout << Derived::Base::val() << std::endl;
}

现场示例:https ://rextester.com/IHR24393

于 2019-03-19T13:35:40.203 回答
1

您的问题不是私有/朋友声明(即使“val”是公共的,代码也不会编译),您的问题是在实例化

static constexpr bool val = Drvd::val

Drvd 仍然是不完整的类型。请参阅下面有关如何使用特征类解决此问题的问题/答案。

C++ 静态多态性 (CRTP) 和使用派生类的 typedef

PS实际上我只是将您的问题标记为重复

于 2019-03-19T15:37:32.950 回答
0

根据@David,问题与Face不完整有关,因为它Base在完成Face.

但是,@David 链接的解决方案有点陈旧,并且遗漏了一些我们可以利用的技巧。也就是说,@ms 向我们展示了static constexpr函数是好的——而且也是基于我自己的实验——我们真的只需要处理这种特殊的static constexpr变量情况,也许还需要处理从Derived.

以下(现场示例)展示了如何解决这个问题,同时将每个类封装到它自己的 h 文件中,使其更加简洁:

#include <iostream>

// Begin: h-file of Base
template<class Drvd>
class ConstValue;

template<class Drvd>
class Base
{
public:
    static constexpr bool val = ConstValue<Drvd>::val;
};
// End: h-file of Base

// Begin: h-file of Derived
class Derived;

template<>
class ConstValue<Derived>
{
public:
    static constexpr bool val = true;
};

class Derived : public Base<Derived>
{
    friend class Base<Derived>;
private:
    static constexpr bool val = true; // optional
};
// End: h-file of Derived

// Main
int main()
{
    std::cout << Derived::Base::val << std::endl;
}

总体思路是,对于需要从 访问的每个constexpr,我们可以创建一个封装变量的类,然后为每个使用的类重载。BaseDerivedDerivedBase

于 2019-03-19T18:08:27.643 回答