以下程序在Cygwin GCC 4.8.2中编译和运行,但在MSCV 2008(或MSVC 2013)中不编译和运行。
#include <iostream>
template<typename T>
struct Base
{
static const unsigned BAR = T::FOO;
static void func()
{
std::cout << BAR << std::endl;
}
};
template<typename T>
struct Derived : Base<Derived<T> >
{
static const unsigned FOO = 42;
};
int main()
{
Derived<int>::func();
}
MSVC 错误
Test.cpp(6) : error C2039: 'FOO' : is not a member of 'Derived<T>'
with
[
T=int
]
Test.cpp(16) : see reference to class template instantiation 'Base<T>' being compiled
with
[
T=Derived<int>
]
Test.cpp(24) : see reference to class template instantiation 'Derived<T>' being compiled
with
[
T=int
]
Test.cpp(6) : error C2065: 'FOO' : undeclared identifier
Test.cpp(6) : error C2057: expected constant expression
此程序是否符合还是 MSCV 问题?另外,有解决方法吗?
编辑 2 :在派生类声明后拒绝初始化就足够了。
我可以让 MSVC 和 Clang 编译您的程序的唯一方法是:
- 拒绝 Base::BAR 派生类声明后的 BAR 初始化
编辑:我认为这是正常的,因为在您的代码中,编译器在编译 Base 时没有办法知道 T::FOO 将存在并且将是一个常量值。
当前来源是:
#include <iostream>
template<typename T>
struct Base
{
static const unsigned BAR;
static void func()
{
std::cout << BAR << std::endl;
}
};
template<typename T>
struct Derived : Base<Derived<T> >
{
static const unsigned FOO = 42;
};
template<typename T>
const unsigned Base<T>::BAR = T::FOO;
int main()
{
Derived<int>::func();
}
您可以通过不从 Base 派生 Derive 来打破 Base 和 Derived 之间的依赖循环(在您编写的示例中不需要这样做)
顺便说一下,clang 也无法编译您的示例并给出与 vstudio 相同的错误
#include <iostream>
template<typename T>
struct Base
{
static const unsigned BAR = T::FOO;
static void func()
{
std::cout << BAR << std::endl;
}
};
struct Derived
{
static const unsigned FOO = 42;
};
int main()
{
Base<Derived>::func();
}