我的业余爱好库的基本组件必须与C++ 98和C++ 11编译器一起使用.要了解和欣赏自己,我创建了几个类型支持的功能(如C++ 98级的实现enable_if,conditional,is_same,is_integral为了使用它们的时候没有C++ 11的支持等...).
然而,当我实施时,is_constructible我陷入困境.有没有任何模板魔术(某种SFINAE),我可以用它来实现它而不需要C++ 11支持(declval)?
当然在C++ 03中没有可变参数模板支持,所以我将把实现专门化到一定深度.主要问题是,是否存在可以决定T是否可以从给定类型构造的技术.
我认为以下代码格式正确:
template< typename T >
using IsSigned = std::enable_if_t< std::is_signed_v< T > >;
template< typename T, IsSigned< T >... >
T myAbs( T val );
Run Code Online (Sandbox Code Playgroud)
其他人则说它格式错误,因为C ++ 17标准的第17.7(8.3)节:
知道哪些名称是类型名称,就可以检查每个模板的语法。该程序格式错误,无需诊断,如果:(...)可变参数模板的每个有效专业化都需要一个空模板参数包,或者(...)
我认为这IsSigned< T >...是一个依赖的模板参数,因此无法在模板定义时对照§17.7(8.3)进行检查。IsSigned< T >例如可能是voidTs的一个子集,int另一个子集或替换失败。对于void子集,确实是这样,空模板参数包将是唯一有效的专业化,但是int子集可以具有许多有效的专业化。这取决于实际T参数。
这意味着编译器必须在模板实例化之后检查它,因为T之前是未知的。到那时,完整的参数列表是已知的,可变参数为零。该标准规定以下内容(第17.6.3(7)节):
当N为零时,扩展的实例化将生成一个空列表。这样的实例化不会改变封闭结构的句法解释
这就是为什么我认为它的格式正确。
我想创建一个 constexpr param 结构。它的几个成员将由 constexpr 函数计算。喜欢:
class Params {
public:
static constexpr size_t featureWinW{ 7 };
static constexpr size_t featureWinH{ 7 };
private:
static constexpr size_t getKernelSize()
{
//complex calculation
return 20;
}
public:
static constexpr size_t kernelSize{ getKernelSize() };
}
Run Code Online (Sandbox Code Playgroud)
我知道 getKernelSize 就像是在类外部定义的,所以代码是错误的:
error: ‘static constexpr size_t Params::getKernelSize()’ called in a constant expression before its definition is complete
Run Code Online (Sandbox Code Playgroud)
我应该如何重新格式化我的代码以使其有效,即使是具有类似私有计算函数的专用命名空间也不会产生垃圾邮件?
从 C++20 std::atomics 开始,有等待和通知操作。使用 is_always_lock_free 我们可以确保实现是无锁的。使用这些积木构建无锁互斥锁并不那么困难。在简单的情况下,锁定将是比较交换操作,或者如果互斥体被锁定则等待。这里最大的问题是这是否值得。如果我可以创建这样的实现,那么 STL 版本很可能会更好、更快。然而,我仍然记得当我在 2016 年看到 QMutex 如何优于 std::mutex QMutex 与 std::mutex时,我是多么惊讶。那么您认为我应该尝试这样的实现还是 std::mutex 的当前实现已经足够成熟,可以进行远远超出这些技巧的优化?
更新 我的措辞不是最好的,我的意思是实现可以在快乐的路径上无锁(从未锁定状态锁定)。当然,如果我们需要等待获取锁,我们应该被阻塞并重新调度。在大多数平台上,atomic::wait 很可能不是通过简单的自旋锁实现的(现在让我们忽略极端情况),所以基本上它实现了 mutex::lock 所做的相同的事情。所以基本上,如果我实现这样一个类,它将执行与 std::mutex 完全相同的操作(同样在大多数流行平台上)。这意味着 STL 可以在支持这些技巧的平台上的互斥实现中使用相同的技巧。就像这个 spinlock,但我会使用原子等待而不是旋转。我应该相信我的 STL 实现是他们这样做的吗?