如何用decltype实现一个不太通用的std::is_constructible

How to implement a less generic std::is_constructible with decltype

本文关键字:std is constructible 实现 decltype 何用 一个      更新时间:2023-10-16

假设这是可能的,但我不太确定。基本上,我所寻找的是一种在编译时在使用默认构造函数或通过引用获取一个参数的构造函数之间切换的方法。

T* create<T>()
{
return new T(1); // if possible
}
T* create<T>()
{
return new T(); // fallback to here
}

我使用的是VS2010编译器,它不支持std::is_constructible,但我可以使用decltype

我深入研究了VS2012 type_traits标头,并查看了std::is_constructible的实现,结果我有点转向了。我不明白人们是怎么写代码的。标题是我见过的最复杂的代码。不管怎样,我看到它使用了decltype,这让我思考,希望有更有经验的人能给我一个答案。

在完成@ipc的回答后,我确定了以下代码

// std::declval is not supported by VS2010
template <typename T> typename std::add_rvalue_reference<T>::type declval();
template <class T, class R0>
decltype(new T(declval<R0>()))
createInstance_(R0& r0, int = 0)
{
return new T(r0);
}
template <class T, class R0>
T*
createInstance_(R0&, ...)
{
return new T();
}

上面的代码会起作用,但它确实混淆了IntelliSense引擎,无论如何,我认为通过简单地使用默认参数可以省略额外的函数是很好的。我已经用VS2010测试了这段代码,它编译得很好,并按预期运行。

我没有VS2010来检查它是否在那里编译,但以下内容与您的示例相匹配。

template <typename T> // if std::declval is not supported by VS10
typename std::add_rvalue_reference<T>::type declval();
template <typename T>
decltype(new T(declval<std::string>()))
create_(std::string param, int) { return new T(param); }
template <typename T>
T * create_(std::string, ...) { return new T(); }
template <typename T>
T * create(std::string param) { return create_<T>(param, 0); }
int main()
{
std::cout << *create<int>("a") << 'n';
std::cout << *create<std::string>("b") << 'n';
}

输出:

0
b