c++ - 模板类中非模板成员函数的 requires 子句

标签 c++ visual-studio templates require c++20

我有一个简单的模板类 A , 如果满足某些要求,我想启用一个功能。
解决方案 1 - requires条款
我尝试的第一个解决方案如下:

template <class T>
class A
{
public:
    void a(void) requires (same_as<T, int>)
    {
        std::cout << "a" << std::endl;
    };
};
这很好用,我可以拨打 A<int>().a()但不是 A<char>().b(); .此外,IntelliSense 正确报告正确识别 Visual Studio 中的使用错误。
然后我尝试将函数定义移到类之外,我在 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;
}
您认为我的代码不正确还是 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;
}

解决方案 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;
}
该解决方案与#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) {};
};
这会很好用,但在某些情况下可能会变得非常复杂,并且当嵌套了一堆级别时,调试起来非常不愉快

你有什么建议/更好的解决方案吗?
提前致谢

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

    MSVC C++ Features声明 P0734R0 Concepts可从 VS 2019 16.3 获得。
    您可能正在使用 VS 2017,它对 C++20 的支持与 MSVC 不同吗?

    关于c++ - 模板类中非模板成员函数的 requires 子句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63338629/

    相关文章:

    C++ - 我如何误用 istringstream 忽略?

    C++ 代码比它的 C 等效代码慢?

    javascript - QList<int> 不能用作 Repeater 的模型

    visual-studio - 为什么 nuget Bootstrapper 使用如此多的链接类

    c++ - dlib : Unable to open face_landmark_detection_ex for reading?

    c# - 我如何使用 Javascript 获取 ASP.Net 网格元素

    c++ - 使用非 constexpr 对象的静态 constexpr 成员变量作为模板参数

    java - 使用 docx4j 在同一文档中用新数据重新填充 docx 模板

    c++ - rand() 在每次函数调用时产生相同的结果(使用 srand(time(0))

    c++ - 具有可变模板参数的成员函数的显式特化