模板化类中模板化方法的专用化 [重复]

Specialization of templated method in a templated class [duplicate]

提问人:Mad Physicist 提问时间:11/9/2023 更新时间:11/9/2023 访问量:101

问:

我有一个简单的模板类,里面有一个模板方法:

#include <iostream>
#include <optional>

template <typename T>
class Test
{
public:
    template <typename U>
    std::optional<U> test() { return std::nullopt; }

    std::optional<double> test() { return std::make_optional<double>(3.0); }
};

int main()
{
    Test<int> t;
    std::cout << t.test<int>().value_or(100) << " " << t.test<double>().value_or(100) << std::endl;
}

我希望程序打印或而不是.我如何使方法专用化,以便它返回一个非空的可选值?100 3.0100 3100 100testTest3.0

除了上述内容之外,我还尝试在专业化之上添加内容。这会导致编译器错误(使用 GCC 9.4.0 运行):template<>gcc -std=c++17 test.cpp

test.cpp:11:14: error: explicit specialization in non-namespace scope ‘class Test<T>’
   11 |     template<>
      |     
C++ 模板 类模板

评论

1赞 n. m. could be an AI 11/9/2023
你上面所拥有的不是专业化,而是超载。如果不对成员模板的封闭类进行专用化,则无法对其进行专用化。
0赞 user12002570 11/9/2023
这是一个众所周知的 gcc 错误。Dupe:非命名空间范围内的显式专用化不会在 GCC 中编译
1赞 n. m. could be an AI 11/9/2023
@user12002570 这不是那个错误。尝试将专业化移出类范围。

答:

0赞 wohlstad 11/9/2023 #1

您可以通过以下方式进行专业化:testdouble

#include <iostream>
#include <optional>

template <typename T>
class Test
{
public:
    template <typename U>
    std::optional<U> test() { return std::nullopt; }

    // Specialization for double:
    template <>
    std::optional<double> test() { return std::make_optional<double>(3.0); }
};

int main()
{
    Test<int> t;
    std::cout << t.test<int>().value_or(100) << " " << t.test<double>().value_or(100) << std::endl;
}

输出:

100 3

更新:
此解决方案适用于 MSVC,但不适用于 GCC。在此处和此处查看更多信息。
GCC 的可能解决方法是使用而不是专用化:
if constexpr

template <typename T>
class Test
{
public:
    template <typename U>
    std::optional<U> test() 
    { 
        if constexpr (std::is_same_v<U, double>)
        {
            return std::make_optional<double>(3.0);
        }
        return std::nullopt; 
    }
};

评论

0赞 Mad Physicist 11/9/2023
您使用的是哪个编译器命令和版本?
0赞 wohlstad 11/9/2023
可视化Studio 2022 (MSVC)
0赞 wohlstad 11/9/2023
我现在看到了这一点,这意味着在这种情况下 MSVC 是非标准的......
0赞 n. m. could be an AI 11/9/2023
@wohlstad 标准已经确定(但 GCC 没有)。在允许主模板定义的任何范围内都允许显式专用化。但是,对非专用模板的成员进行显式专用化似乎是不合法的(标准对此不是很清楚)。
2赞 wohlstad 11/9/2023
@n.m.couldbeanAI 我明白了。我想在遵守标准方面,解决方法会更好。if constexpr