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

时间:2020-08-10 10:43:21

标签: 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编译器的bug /功能不完整?


解决方案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)

2 个答案:

答案 0 :(得分:0)

keras blog指出MSVC C++ Features在VS 2019 16.3中可用。

您是否可以使用VS 2017,它不支持MS ++对C ++ 20的支持?

答案 1 :(得分:0)

我建议您最好不要使用C ++ 20,因为Visual Studio对C ++ 20的支持尚未完成。如果您没有使用VS2019,建议您可以更新到最新版本的VS2019。然后在Preview - Features from the Latest C++ Working Draft (std:c++latest)中设置Properties->General->C++ Language Standard