c++ - 用作模板默认参数时,不会调用完全专用的重载方法

标签 c++ templates c++17

我希望能够通过调用重载函数之一(即具有完全特化的模板)来指定默认的非类型模板参数。以下代码代表了该问题:我期望 FieldType2 getDefaultField<FieldType2>()要打印,但是 Called getDefaultField() !已打印。

#include <iostream>

enum class FieldType1 {
    Description1,
    Description2,
    Description3
};

enum class FieldType2 {
    Description1,
    Description2,
    Description3
};

template<class FiledType>
struct FieldDescription {
    constexpr static int startPos{0};
    constexpr static FieldType fieldType{}; 
};

struct ConcreteField2 : public FieldDescription<FieldType2> {};

template<class FieldType>
constexpr FieldType getDefaultField() {
    return FieldType{};
};

template<>
constexpr FieldType1 getDefaultField<FieldType1>() {
    return FieldType1::Description1;
};

template<>
constexpr FieldType2 getDefaultField<FieldType2>() {
    return FieldType2::Description3;
};

template<class FieldDescr,
        decltype(FieldDescr::fieldType) fieldType = getDefaultField<decltype(FieldDescr::fieldType)>()>
void process() {
    if (fieldType == FieldType2::Description3) {
        std::cout << "FieldType2 getDefaultField<FieldType2>()" << std::endl;
    }
    if (fieldType == FieldType2::Description1) {
        std::cout << "Called getDefaultField() !" << std::endl;
    }
}

int main() {
    process<ConcreteField2>();

    return 0;
}   

最佳答案

decltype(FieldDecr::fieldType)const FieldType2 而不是 FieldType2。因此您的专业不匹配,因此使用了主要模板。

您可以使用std::decay_t:

getDefaultField<std::decay_t<decltype(FieldDescr::fieldType)>>()

Demo

但正如评论中所建议的,虚拟成员的用法很奇怪,常规的 using type = FiledType; 更惯用。

关于c++ - 用作模板默认参数时,不会调用完全专用的重载方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66563678/

相关文章:

c++ - 如何为包含头文件的目标编写 makefile?

c++ - 带有别名的 SFINAE,重载问题

c++ - 使用依赖于类型的模板名称的声明

c++ - 从传递给模板函数的内部类实例中提取外部类类型

c++ - 指向 C++17 中 constexpr 静态成员的 constexpr 指针

c++ - 给定一组字符和长度的排列

c++ - 如何将 cv::Mat 转换为 cv::Vec3f?

c++ - 在固定模板参数的同时扩展模板类

c++ - 如何添加到 std::variants ?

c++ - istrstream 的更好替代品?