Dra*_*n D 1 c++ templates clang
这是我的问题的简单版本:
#include <iostream>
template<typename T>
class Extractor
{
public:
static const int& value;
};
class Bar
{
};
template<typename T>
class Foo
{
public:
Foo() {
m_value = Extractor<Bar>::value;
}
public:
int m_value;
};
int gValue = 42;
template<> const int& Extractor<Bar>::value = gValue;
int main()
{
Foo<Bar> test;
std::cout << " Hello, world " << test.m_value << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
g++ 没有给出错误并且显示正确。
clang 返回以下错误消息:
1184815205/source.cpp:30:39: error: explicit specialization of 'value' after instantiation
template<> const int& Extractor<Bar>::value = gValue;
^
1184815205/source.cpp:22:35: note: implicit instantiation first required here
m_value = Extractor<Bar>::value;
Run Code Online (Sandbox Code Playgroud)
规范指定:
如果模板、成员模板或类模板的成员被显式特化,则应在第一次使用该特化之前声明该特化,这将导致发生隐式实例化,在发生这种使用的每个翻译单元中; 无需诊断。
在第一次使用该专业化之前,
我认为我的代码片段遵循此规则,导致模板的实际实例化出现在函数中main(), Foo 构造函数尚不应该被编译。我错过了什么吗?
提高模板专业化可以解决这个问题,但我负担不起。
由于Extractor<Bar>不依赖于T,因此可以实例化它以value在声明中查找或在实际实例化时进行查找。Clang 更加渴望,这是被允许的。
最简单的解决方法是简单地声明专门化Extractor<Bar>::value并稍后定义它:
class Bar
{
};
template<> const int& Extractor<Bar>::value; // Declaration here
template<typename T>
class Foo
{
public:
Foo() {
m_value = Extractor<Bar>::value; // Will use the specialzation
}
public:
int m_value;
};
int gValue = 42;
template<> const int& Extractor<Bar>::value = gValue; // Actual definition
Run Code Online (Sandbox Code Playgroud)
或者伪造对模板参数的依赖:
template<typename T, typename... Dependencies>
struct dependent_type_identity { using type = T; };
template<typename T, typename... Dependencies>
using dependent_type_identity_t = typename dependent_type_identity<T, Dependencies...>::type;
m_value = Extractor<dependent_type_identity_t<Bar, T>>::value;
// Or
m_value = dependent_type_identity_t<Extractor<Bar>, T>::value;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
112 次 |
| 最近记录: |