简体   繁体   English

在VS2017中编译错误C2027,但在小对象优化的情况下不编译Clang

[英]Compile error C2027 in VS2017 but not Clang with small object optimization

So I'm trying to implement small object optimization in a project of mine, but I'm running into a strange compiler error. 因此,我试图在我的项目中实现小对象优化,但是我遇到了一个奇怪的编译器错误。 Here's some simplified code that reproduces the issue: 这是一些重现此问题的简化代码:

#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);
}

Basically, I need to take an arbitrary object, put it in a wrapper, and instantiate an instance of the wrapper in the padding, but I need to use one wrapper for types that can fit in the padding and a different one for types that are too large (one of the wrappers stores the object in place while the other allocates external space for it). 基本上,我需要获取一个任意对象,将其放入包装器中,并在填充中实例化包装器的一个实例,但是我需要为适合填充器的类型使用一个包装器,而对于太大(包装器之一将对象存储在适当位置,而另一个包装器为其分配外部空间)。 And obviously I'd like to support perfect forwarding. 很显然,我想支持完美的转发。

Unfortunately, VS2017 gives me the following compiler error: error C2027: use of undefined type 'Wrapper<decay<_Ty>::type>' . 不幸的是,VS2017给了我以下编译器错误: error C2027: use of undefined type 'Wrapper<decay<_Ty>::type>' I can compile it just fine with Wrapper<T> rather than Wrapper<std::decay_t<T>> , but I think I need to use the decayed type. 我可以使用Wrapper<T>而不是Wrapper<std::decay_t<T>> ,但是我认为我需要使用衰减类型。 Clang compiles it fine as is. Clang可以正常编译。

So what's the problem here? 那么这是什么问题呢? I'm a bit stuck. 我有点卡住了。

Possibly a bug in the VS compiler. VS编译器中的错误。

I can get it to compile with a slightly different form of the sfinae condition, using a default type instead of a default value: 我可以使用默认类型而不是默认值,以稍微不同形式的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);
}

No real explanation of why this should work better, it's just the form I usually use. 没有真正的解释为什么它应该更好地工作,这只是我通常使用的形式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM