c++ 如何根据成员变量的存在性模板化函数

2ledvvac  于 2022-12-30  发布在  其他
关注(0)|答案(1)|浏览(228)

下面是一个简单的例子,我不知道如何使函数明确无误。我使用echo检查SFINAE成员变量类型的完整性,并将void作为返回类型回显。

// Example program
#include <iostream>
#include <string>
#include <type_traits>

namespace detail {
    struct X {
        int x;
    };
    
    struct Y {
        int y;
    };
    
    template <typename V, typename... T>
    using echo = V;
    
    template <typename T>
    echo<void, decltype(std::declval<T>().x)> template_print(T& t) {
        std::cout << "x = " << t.x << std::endl;
    }
    
    template <typename T>
    echo<void, decltype(std::declval<T>().y)> template_print(T& t) {
        std::cout << "y = " << t.y << std::endl;
    }
}

int main()
{
    detail::X a{.x = 1};
    detail::Y b{.y = 2};
    detail::template_print(a);
    detail::template_print(b);
    return 0;
}
vaqhlq81

vaqhlq811#

我不认为这是一个模棱两可的问题,而是一个重新定义的问题。
如果您将echo别名模板的实现从“direct”更改为“indirect”,则可以解决您遇到的问题,如以下代码片段所示。

template <typename T, typename... Ts>
struct Echo
{
    using type = T;
};
template <typename T, typename... Ts>
using echo = typename Echo<T, Ts...>::type;

请注意,有些人可能建议您使用std::void_t,但出于完全相同的原因,这在这里也不起作用。
这个问题有点复杂,但是可以通过使用间接别名模板(如上面最终解析为嵌套类型的模板)而不是直接别名模板来避免。
冒着我自己的演讲的风险,我唯一看到的关于这个的解释是在CppCon 2021 video的第一部分。

相关问题