模板类中非模板成员函数的 require 子句

Luc*_*cci 11 c++ templates visual-studio c++20 requires-clause

我有一个简单的模板类A。如果满足某些要求,我想启用一项功能。

解决方案 1 -requires子句

我尝试的第一个解决方案如下:

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

这效果非常好。我可以打电话,A<int>().a()但不能A<char>().a();。此外,IntelliSense 可以正确识别 Visual Studio 中的使用错误。

我尝试将函数定义移到类之外,但在 Visual Studio 中出现 C2511 编译器错误。在海湾合作委员会,它工作得很好。

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;
}
Run Code Online (Sandbox Code Playgroud)

您认为我的代码不正确还是 Visual Studio 编译器错误/功能不完整?


解决方案2-static_assert

该解决方案在某些情况下有效,但如果您尝试显式模板实例化(例如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;
}
Run Code Online (Sandbox Code Playgroud)

解决方案 3 -enable_if

(错误的)

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;
}
Run Code Online (Sandbox Code Playgroud)

该解决方案与#2 具有相同的问题。而且,我不想添加一些乍一看无法理解的模板。


解决方案 4 - 一些奇怪的编译时继承

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) {};
};
Run Code Online (Sandbox Code Playgroud)

这会很好用,但在某些情况下可能会变得非常复杂,并且当嵌套一堆级别时,调试会非常不愉快。


您有什么建议/更好的解决方案吗?

提前致谢。


编辑:

  • 解决方案#3不起作用,我犯了一个错误;
  • 我正在使用 msvc 16.7.0,构建工具 x64/x86 (v14.27)

Big*_*eny 0

MSVC C++ 功能指出P0734R0 概念可从 VS 2019 16.3 开始使用。

您是否可能使用 VS 2017,它对 C++20 和 MSVC 的支持不一样?