【问题标题】:How to template specialize a function based on member variable existenceHow to template specialize a function based on member variable existence
【发布时间】:2022-12-27 22:00:25
【问题描述】:

Here is a simple example of what I want, but I don't know how to make the functions unambiguous. I am using echo to check the integrity of the type of the member variable for SFINAE and echo back void as the return type.

// 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;
}

【问题讨论】:

    标签: c++ template-meta-programming


    【解决方案1】:

    I would not call this an issue of ambiguity, but of redefinition.

    You can fix the issue you are having if you change the implementation of your echo alias template from "direct" to "indirect" as in the following sn-p.

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

    Note that some may advise that you use std::void_t, but that would not work here either - for the exact same reason.

    The issue is a bit complex, but you can avoid it by using an indirect alias template (like the one above that eventually resolves to the nested type) rather than a direct alias template.

    At risk of shilling my own talk, the only place I've seen any sort of explanation of this is in the first part of this CppCon 2021 video.

    【讨论】:

      猜你喜欢
      • 2022-12-02
      • 2022-12-02
      • 2022-12-01
      • 2022-12-02
      • 1970-01-01
      • 2022-12-02
      • 2022-12-02
      • 2022-12-02
      • 2022-12-02
      相关资源
      最近更新 更多