简体   繁体   English

无法使用 std::enable_if 在 g++/clang++ 上编译显式专用模板结构

[英]Failing to compile explicitly specialized template struct on g++/clang++ with std::enable_if

I've tried to compile this with msvc and it compiles fine.我试图用 msvc 编译它,它编译得很好。 On the other hand I failed to compile it with g++ and clang++.另一方面,我未能用 g++ 和 clang++ 编译它。 Error I get is no type named 'type' in 'struct std::enable_if<false, void>' .我得到的错误是no type named 'type' in 'struct std::enable_if<false, void>' How would I resolve this error?我将如何解决此错误?

#include <type_traits>

template <bool v>
struct a {

    template <typename T = typename std::enable_if<v>::type>
    void function();

};

template struct a<false>;
template struct a<true>;

template<bool v>
template<typename T>
void a<v>::function() { }

int main() {

}

I'm trying to make void function visible if passed bool template is true .如果传递的bool模板为true ,我正在尝试使void function可见。

You are not using SFINAE correctly because the bool you pass to enable_if (which is v ) is not dependent on the function template parameters.您没有正确使用 SFINAE,因为您传递给enable_ifbool (即v )不依赖于 function 模板参数。

The canonical way to selectively add or remove members of a class template is to use template specialization.选择性地添加或删除 class 模板成员的规范方法是使用模板特化。 For example:例如:

template <bool v>
struct a {
    void function();
};

template< >
struct a<false> {
};

Now, only a<true> will have the function member.现在,只有a<true>将具有function成员。 If you have many common members that should be present in a regardless of v , you can move these members to a base class and derive both specializations from it:如果您有许多公共成员应该存在于a而与v无关,您可以将这些成员移动到基础 class 并从中派生两个专业化:

struct a_common {
    void common_function();
};

template <bool v>
struct a : public a_common {
    void function();
};

template< >
struct a<false> : public a_common {
};

This can be achieved with SFINAE as well, but it will require a bit of a trick.这也可以通过 SFINAE 实现,但需要一些技巧。 As mentioned above, we need to make function a template, and we need to ensure that the condition used in enable_if depends on its template parameters.如上所述,我们需要将function一个模板,并且我们需要确保enable_if中使用的条件依赖于它的模板参数。 Since we don't have any template parameters, we need to add a dummy one:由于我们没有任何模板参数,我们需要添加一个虚拟参数:

template <bool v>
struct a {
    template<
        typename Dummy = void,
        typename = typename std::enable_if<
            std::is_same< Dummy, Dummy >::value && v
        >::type
    >
    void function();
};

Here, we use is_same trait to introduce a formal dependency on the Dummy template parameter when calculating the first template parameter of enable_if .在这里,我们使用is_same trait 在计算enable_if的第一个模板参数时引入对Dummy模板参数的正式依赖。 Naturally, the result of is_same will be true , so effectively v decides whether the function template can be instantiated.自然地, is_same的结果将为true ,因此v有效地决定了function模板是否可以被实例化。

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

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