std::disjuction 在传递给模板函数的参数包中找不到类型

std::disjuction not finding type in parameter pack passed to template function

我正在尝试使用 std::disjuction 来测试参数包是否包含 std::wstring,但我尝试过的任何方法似乎都不想让它成为 return 我的值'我期待着。

这是目前的代码 (https://godbolt.org/z/x99M8avYE):

#include <string>
#include <iostream>
#include <type_traits>

template <typename ...Ts>
using HasWS = std::disjunction<std::is_same<std::wstring,Ts>...>;

template <typename T, typename ...Ts>
using HasWS2 = std::disjunction<std::is_same<T,Ts>...>;

template<typename... Args>
void f(Args&&... args) {
    std::cout << HasWS<Args...>::value << std::endl;
    std::cout << HasWS2<std::wstring, Args...>::value << std::endl;
    std::cout << std::disjunction_v<std::is_same<std::wstring, Args>...> << std::endl;
    (std::cout << typeid(args).name() << std::endl, ...);
}

template <typename T, typename ...Ts>
using areT = std::disjunction<std::is_same<T,Ts>...>;

int main() {
    std::wstring wstr(L"abc");
    std::string str("def");

    static_assert(areT<std::wstring,std::string,std::wstring>::value);    
    static_assert(HasWS<std::wstring,decltype(wstr),decltype(str)>::value);
    static_assert(std::is_same<decltype(wstr), std::wstring>::value);
    
    f(wstr, str);
    f(str, str);
    f(wstr, wstr);

    std::cout << std::is_same_v<decltype(wstr), std::wstring> << std::endl;

    return 0;
}

如您所见,我正在尝试用不同的方式调用 disjuction,但其中 none 会发现 wstring 和 return 为真。我什至弯腰打印出包中每个元素的类型并使用 is_same 来确保 wstr 实际上是 wstring.

这到底是怎么回事?这与我不知道的模板的 pack 参数有关吗?

注意f接收的参数类型是转发引用Args&&,所以当你传入一个左值wstr时,Args 将被实例化为 std::wstring& 而不是 std::wstring,您应该删除引用,例如

template<typename... Args>
void f(Args&&... args) {
    std::cout << HasWS<std::remove_reference_t<Args>...>::value << std::endl;
    std::cout << HasWS2<std::wstring, std::remove_reference_t<Args>...>::value << std::endl;
    std::cout << std::disjunction_v<std::is_same<std::wstring, std::remove_reference_t<Args>>...> << std::endl;
}

Demo