所以我试图在我的项目中实现小对象优化,但是我遇到了一个奇怪的编译器错误。下面是一些重现该问题的简化代码:
#include <type_traits>
template<typename T>
class Wrapper {
T thing;
public:
Wrapper(T&& thing) {
// ...
}
};
class Test {
static const size_t PADDING_SIZE = 64;
public:
template<
typename T,
std::enable_if_t<sizeof(Wrapper<std::decay_t<T>>) <= PADDING_SIZE, int> = 0
// Error on this line ^
>
Test(T&& thing) {
new (padding) Wrapper<std::decay_t<T>>(std::forward<T>(thing));
}
char padding[PADDING_SIZE];
};
int main() {
auto t = Test(0.0f);
}
基本上,我需要获取一个任意对象,将其放入包装器中,并在填充中实例化包装器的实例,但我需要对适合填充的类型使用一个包装器,并为适合填充的类型使用不同的包装器太大的类型(其中一个包装器将对象存储在适当的位置,而另一个包装器为其分配外部空间)。显然我想支持完美转发。
不幸的是,VS2017 给出了以下编译器错误:error C2027: use of undefined type 'Wrapper<decay<_Ty>::type>'
。我可以用 Wrapper<T>
很好地编译它而不是Wrapper<std::decay_t<T>>
,但我想我需要使用腐烂的类型。 Clang 按原样编译它。
那么这里有什么问题呢?我有点卡住了。
最佳答案
可能是 VS 编译器中的错误。
我可以使用默认类型而不是默认值,以稍微不同形式的 sfinae 条件进行编译:
#include <type_traits>
#include <new>
template<typename T>
class Wrapper {
T thing;
public:
Wrapper(T&& ) {
// ...
}
};
class Test {
static const size_t PADDING_SIZE = 64;
public:
template<
typename T,
class = std::enable_if_t<sizeof(Wrapper<std::decay_t<T>>) <= PADDING_SIZE>
>
Test(T&& thing) {
new (padding) Wrapper<std::decay_t<T>>(std::forward<T>(thing));
}
char padding[PADDING_SIZE];
};
int main() {
auto t = Test(0.0f);
}
没有真正解释为什么这应该更好,这只是我通常使用的形式。
关于c++ - 在VS2017中编译错误C2027,但使用小对象优化的Clang则不然,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47686611/