- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在尝试禁用具有非 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);
错误信息如下:
error C2535: 'A::A(U &&)': member function already defined or declared (live example).
这意味着,SFINAE 的两个条件都成功并且两个 ctors 都被使用。
我继续尝试以下方法:
#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"));
}
幸运的是它可以编译并且工作正常(live example)。
到目前为止,我对第二种解决方案非常满意,但我真的不明白为什么使用模板化参数启用/禁用 ctor 的第一种方法不起作用。
最佳答案
条件不是都为真,那是不可能的。您可以放心,因为第二种方法有效,如果两者都成立,则不会发生这种情况。
重要的是要记住,默认模板参数不是函数模板签名的一部分。如果我们稍微减少两个 c'tors 到他们的签名,我们会得到这个:
template <typename U, typename>
A(U&& val)
{
}
template <typename U, typename>
A(U&& val)
{
}
两者是一模一样的。所以发生的是 U
的模板参数推导,并尝试进行替换以查看选择哪个重载。即使我们无法完成其中一个重载的模板参数推导(最后一个参数在其中一个中总是下落不明),但在尝试推导过程时,我们仍然会找到两个具有相同签名的模板。所以程序变成病式。
第二种方法可行,因为签名本身取决于正在评估的 enable_if
。这就是为什么两个重载之一将始终被静默删除,就好像它从未存在过一样。
关于C++ SFINAE:const char[] 与 std::string 的 is_constructible,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49975035/
最近我试图检测特定私有(private)构造函数的存在,但遇到了 std::is_constructible 仅检查直接上下文的问题,因此不会识别任何此类构造函数。经过一些研究,我确实看到了一个答案
我想从我可以用模板参数构造的列表中找到类型。在这个例子中: using my_type = typename get_constructible::type; my_type 必须是 std::str
我想检测一个类是否有显式转换运算符。我已尝试使用 is_constructible,但以下断言因 msvc 19.00.23506 而失败。 #include #include struct Fo
这个问题在这里已经有了答案: Why does is_constructible claim something is constructible when it isn't? (2 个答案) 关闭
是否 std::is_constructible工作如果 Arg1是一种可转换为 T 的有效单参数构造函数的类型?当类型具有非模板化转换运算符时它似乎可以工作,但如果转换运算符是模板化的则它不起作用(
以下程序在使用 GCC 4.7 和 clang 3.2 编译时,会产生“1”作为输出。 #include struct foo { template foo(T) {
我有以下代码: #include class A; int main() { std::cout ::value struct is_constructible; T and all ty
源自this话题。也与此有关 topic . 我的问题是为什么 std::is_constructible 在直接上下文中停止?我认为 std::is_constructible 的用户会期望它能够深
我容器的一个构造函数默认构造一个分配器作为默认参数值: template struct my_container { my_container(int n, Allocator alloc = A
我在玩弄模板并尝试实现以下助手。 first_constructible::type 这将返回第一种 Types可从 Args... 构建.第一个问题显然是在 struct 中有两个参数包,所以我将用
std::is_constructible 的规则是什么?处理私有(private)构造函数?给定以下代码: #include class Class { private: Class()
这个问题在这里已经有了答案: C++98/03 std::is_constructible implementation (4 个答案) 关闭 5 年前。 到目前为止,我在网上找不到任何 ELI5。
我的爱好库的基本组件必须与 C++98 和 C++11 编译器一起使用。为了学习和享受自己,我创建了几种类型支持功能的 C++98 实现(如 enable_if、conditional、is_same
std::is_constructible::value 的结果不一致.我对该标准的解释是它应该是错误的。然而,Clang,同时具有 libc++ 和 libstdc++*,给出了 true。 GCC
我在这里冒险,假设这是可能的,但我不太确定。基本上我正在寻找的是一种在编译时在使用默认构造函数或通过引用采用一个参数的构造函数之间切换的方法。 即 T* create() { return n
我目前正在研究一些模板的东西。但我有一个问题。我有一堂这样的课 class myobj{ public: int val; char single; string na
我目前正在研究一些模板的东西。但我有一个问题。我有一堂这样的课 class myobj{ public: int val; char single; string na
在评估 std::is_constructible 和 std::is_destructible 时,Clang 和 GCC 似乎不遵守 friend 声明。 关于`is_constructible,
std::is_constructible 的预期结果是什么?在具有私有(private)或 protected 析构函数的类型上? 例如,即使只有 friend 可以释放它,我仍然可以在堆上构造这样
我正在尝试禁用具有非 std::string 可构造类型的 ctor。我的第一次尝试是这样的: #include struct A { template ::value>::type>
我是一名优秀的程序员,十分优秀!