gpt4 book ai didi

C++可变参数模板构造函数和通用构造函数

转载 作者:可可西里 更新时间:2023-11-01 17:39:03 28 4
gpt4 key购买 nike

代码如 (c++14):

struct S { int a; int b; };

class C
{
public:
C(char const*, size_t) {} // 1
C(S const&) {} // 2
C(S const*) {} // 3
template<typename ...T> C(T&& ...) {} // 4

// C(S) {} // 5
// C(S*) {} // 6
};

S s { 1, 2 };
C c1 { s }; // calls 4 and not 2
C c2 { "abc", 3 }; // calls 4 and not 1
C c3 { (char const*)"abc", (size_t)3 }; // calls 1 - ok
C c4 { s }; // calls 5 if uncommented
C c5 { &s }; // calls 6 if uncommented
S const s2 {};
C c6 { &s2 }; // calls 3

如果简单构造函数与传递的参数具有完全相同的签名,则调用它。是否有一些技巧可以像往常一样将通用构造函数与可变模板构造函数一起使用,而无需复制类、作为参数传递以及重载构造函数,例如:

C(S const*) {}
C(S*) {}

并且在构造函数中没有额外的标签

最佳答案

创建两层构造函数。然后标记调度。

template<template<class...>class Z, class T>
struct is_template:std::false_type{};
template<template<class...>class Z, class...Ts>
struct is_template<Z, Z<Ts...>>:std::true_type{};

struct foo {
private:
template<class T> struct tag{ explicit tag(int) {} };
public:
foo( tag<std::true_type>, const char*, size_t );
template<class...Ts>
foo( tag<std::false_type>, Ts&&...ts );

public:
foo() = default; // or whatever
template<class T0, class...Ts,
std::enable_if_t<!is_template<tag, std::decay_t<T0>>{},int> =0>
foo(T0&&t0, Ts&&...ts):
foo( tag<typename std::is_constructible< foo, tag<std::true_type>, T0&&, Ts&&... >::type>{0}, std::forward<T0>(t0), std::forward<Ts>(ts)... )
{}
};

“首选”的 ctors 以 std::true_type 为前缀,“不太受欢迎”的 ctors 以 std::false_type 为前缀.

这具有完美转发的常见缺陷。例如,如果您采用初始化列表,您将希望有另一个明确采用它的“公共(public)”构造函数。并且函数名称参数神奇的重载将不起作用。 NULL是一个 int .等等

您可以想象一个版本,它没有两层,而是具有任意数量。 is_constructible< ... >相反,面向公众的 ctor 中的子句被一些找到最高 N 的魔法所取代,使得 tag<N>, blah...可以构建对象(或者,最低 N ,无论你想做什么)。然后它返回类型 tag<N> ,然后调度到该层。

使用这样的技术:

template <typename... T,
typename = std::enable_if_t<!std::is_constructible<C, T&&...>::value>
>
C(T&&... ) { }

遇到a serious problem在路上,正如我们实例化的那样is_constructible它得到错误答案的情况下。实际上,编译器会缓存模板实例化的结果,所以现在 is_constructible 的结果依赖于编译器顺序(我怀疑是 ODR 违规)。

关于C++可变参数模板构造函数和通用构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32957830/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com