简体   繁体   English

模板 class 中的非模板成员 function 的需要子句

[英]requires clause for a non-template member function in a template class

I have a simple template class A , I want to enable a function if some requirements are satisfied.我有一个简单的模板 class A ,如果满足某些要求,我想启用 function 。

Solution 1 - requires clause解决方案 1 - requires子句

The first solution I tried is the following:我尝试的第一个解决方案如下:

template <class T>
class A
{
public:
    void a(void) requires (same_as<T, int>)
    {
        std::cout << "a" << std::endl;
    };
};

This works pretty well, I can call A<int>().a() but not A<char>().b();这很好用,我可以调用A<int>().a()但不能调用 A A<char>().b(); . . Also IntelliSense correctly report correctly identifies usage errors in Visual Studio. IntelliSense 还正确报告正确识别 Visual Studio 中的使用错误。

Then I tried to move the function definition outside the class and I got C2511 compiler error in Visual Studio while in GCC it works fine然后我尝试将 function 定义移到 class 之外,我在 Visual Studio 中遇到 C2511 编译器错误,而在 GCC 中它工作正常

template <class T>
class A
{
public:
    void a(void) requires (same_as<T, int>);
};

template <class T>
void A<T>::a(void)
requires (same_as<T, int>)
{
    std::cout << "a" << std::endl;
}

Do you think my code is incorrect or is it a visual studio compiler bug/incomplete feature?您认为我的代码不正确还是 Visual Studio 编译器错误/功能不完整?


Solution 2 - static_assert解决方案 2 - static_assert

This solution works in some cases, but of course it would cause compile errors if you try an explicit template instantiation (for example template class A<char> ), also IntelliSense would not correctly identify improper usages此解决方案在某些情况下有效,但如果您尝试显式模板实例化(例如template class A<char> )当然会导致编译错误,而且 IntelliSense 也无法正确识别不正确的用法

template <class T>
class A
{
public:

    void a(void);
};

template <class T>
void A<T>::a(void)
{
    static_assert(same_as<T, int>);
    std::cout << "a" << std::endl;
}

Soluton 3 - enable_if解决方案 3 - enable_if

(wrong) (错误的)

template <class T>
class A
{
public:

    template <std::enable_if_t<same_as<T, int>, bool> = true>
    void a(void);
};

template <class T>
template <std::enable_if_t<same_as<T, int>, bool>>
void A<T>::a(void)
{
    std::cout << "a" << std::endl;
}

This solution has the same probelms as #2, moreover I would prefer not to add some non understandable at first sight templates.该解决方案与#2 具有相同的问题,此外,我不希望添加一些乍一看无法理解的模板。


Solution 4 - some weird compile time inheritance解决方案 4 - 一些奇怪的编译时间 inheritance

template <class T>
class A_base { /*common stuff*/ };

template <class T>
class A : public A_base<T>
{
public:
    A_base<T>::A_base;

    /* non-int stuff*/
};

template <>
class A<int> : public A_base<int>
{
public:
    A_base<int>::A_base;

    void a(void) {};
};

This would work well, but it could get quite complex in some situations and very unpleasant for debugging when a bunch of levels are nested这会很好用,但在某些情况下它可能会变得相当复杂,并且在嵌套一堆级别时非常不利于调试


Do you have any advice / better solution?您有什么建议/更好的解决方案吗?

Thanks in advance提前致谢


Edit:编辑:

  • solution #3 does not work, I made a mistake;解决方案#3不起作用,我犯了一个错误;
  • I am using msvc 16.7.0, Build Tools x64/x86 (v14.27)我正在使用 msvc 16.7.0,构建工具 x64/x86 (v14.27)

MSVC C++ Features states that P0734R0 Concepts is available from VS 2019 16.3. MSVC C++ 功能声明P0734R0 概念可从 VS 2019 16.3 获得。

Could you possibly be using VS 2017 which does not have the same support for C++20 with MSVC?您是否可能使用 VS 2017,它对 C++20 和 MSVC 的支持不同?

I suggest you better not use C++20, because Visual Studio's support for C++20 is not yet complete.我建议你最好不要使用 C++20,因为 Visual Studio 对 C++20 的支持还不完整。 If you are not using VS2019, it is recommended that you could update to the latest version of VS2019.如果您没有使用 VS2019,建议您更新到最新版本的 VS2019。 Then set Preview - Features from the Latest C++ Working Draft (std:c++latest) in Properties->General->C++ Language Standard .然后在Properties->General->C++ Language Standard中设置Preview - Features from the Latest C++ Working Draft (std:c++latest)

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

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