template<typename T>
class A
{
public:
A(T &t)
: t_(t){}
T t_;
};
int main()
{
int value;
A<decltype(value)> a(value);
// what I wish for : A a(value);
// which does not compile "missing template argument before 'a'"
}
在A(或其他地方)的声明中是否有一种方式可以暗示编译器T应该自动解析为传递给构造函数的类型?
(理想情况下为c ++ 11,但很高兴听到较少的旧版本)
答案 0 :(得分:6)
C ++ 17是开箱即用的(或者借助演绎指南),以前的版本则不能。
答案 1 :(得分:4)
正如@Quentin回答的那样,仅从C ++ 17开始才有可能。但是,如果您可以调用函数来创建A
对象,那么以下操作应该可以在C ++ 11中完成:
template <class T, class NonRefT = typename std::remove_reference<T>::type>
A<NonRefT> create_A (T && t) {
return A<NonRefT>(std::forward<T>(t));
}
// Or even closer to your original code:
template <class T>
auto create_A (T && t) -> A<decltype(t)> {
return A<decltype(t)>(std::forward<T>(t));
}
尽管您可能想使用std::remove_reference
,但我还是根据您对decltype
的使用来使用std::decay
。
int main () {
int value = 5;
auto a = create_A(value);
}
如果我没记错的话,示例代码有一个极端的情况,即在C ++ 17之前无法正常工作。编译器将取消复制/移动构造函数,以根据a
返回的右值创建create_A()
。但是,它将在编译期间检查A
的复制/移动构造函数(它将不使用)是否可用/可访问。从C ++ 17开始,复制/移动省略是“适当地”完成的,此类代码不需要复制/移动构造函数。 (另外,我可能记错了,它可能正在检查复制/移动分配。)
答案 2 :(得分:2)
在C ++ 11中,您可以创建一个简单的make_A
函数,如下所示:
#include <iostream>
template <typename T>
class A {
public:
A(T &t) : t_(t) {}
T t_;
};
template <typename T>
A<T> make_A(T&& t) {
return A<T>(std::forward<T>(t));
}
int main() {
int value = 0;
auto a = make_A(value);
return 0;
}