C++ SFINAE:const char[] 与 std::string 的 is_constructible

2024-04-18

我正在尝试禁用具有非 std::string 可构造类型的 ctor。我的第一次尝试是这样的:

#include <iostream>

struct A
{
    template <typename U, typename = typename std::enable_if<std::is_constructible<std::string, U>::value>::type>
    A(U&& val)
    {
        std::cout << "A(std::string&& val)" << std::string(std::forward<U>(val)) << std::endl;
    }

    template <typename U, typename = typename std::enable_if<not std::is_constructible<std::string, U>::value>::type>
    A(U&& val)
    {
        std::cout << "A(int&& val)" << val << std::endl;
    }
};

int main()
{
    A a1(1);
    A a2("hello");
    A a3(std::string("hello"));
}

但是编译失败了

A a1(1);

并出现以下错误消息:

错误 C2535: 'A::A(U &&)': 成员函数已定义或声明 (活生生的例子 https://wandbox.org/permlink/IVKLqPY1aSj5Zt5q).

这意味着 SFINAE 的两个条件都成功,并且两个因子都被使用。

我继续尝试以下方法:

#include <iostream>

struct A
{
    template <typename U>
    A(U&& val, typename std::enable_if<std::is_constructible<std::string, U>::value>::type* = nullptr)
    {
        std::cout << "A(std::string&& val)" << std::string(std::forward<U>(val)) << std::endl;
    }

    template <typename U>
    A(U&& val, typename std::enable_if<not std::is_constructible<std::string, U>::value>::type* = nullptr)
    {
        std::cout << "A(int&& val)" << val << std::endl;
    }
};

int main()
{
    A a1(1);
    A a2("hello");
    A a3(std::string("hello"));
}

幸运的是它编译并运行良好(活生生的例子 https://wandbox.org/permlink/yq67DhcV6l2GQi6O).

到目前为止,我对第二个解决方案非常满意,但我不太明白为什么使用模板化参数启用/禁用 ctor 的第一种方法不起作用。


条件不同时成立,那是不可能的。您可以确信第二种方法有效,如果两者都成立,则不会发生这种情况。

重要的是要记住,默认模板参数不是函数模板签名的一部分。如果我们将两个 c'tors 简化为他们的签名,我们会得到:

template <typename U, typename>
A(U&& val)
{
}

template <typename U, typename>
A(U&& val)
{
}

并且两者是相同的。所以发生的事情是模板参数推导U并尝试进行替换以查看选择哪个重载。尽管我们无法完成其中一个重载的模板参数推导(其中一个重载中总是没有考虑最后一个参数),但在尝试推导过程时,我们仍然发现两个具有相同签名的模板。因此该程序变得格式错误。

第二种方法有效,因为签名本身取决于enable_if正在评估中。这就是为什么两个重载之一总是会被默默地删除,就好像它从未存在过一样。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ SFINAE:const char[] 与 std::string 的 is_constructible 的相关文章

随机推荐