编译器推断模板参数
Compiler infering the template argument
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,但很高兴听到不那么旧的版本)
C++17 开箱即用(或借助演绎指南),以前的版本不能。
正如@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
based on your use of decltype
, though you might want to use std::decay
。
int main () {
int value = 5;
auto a = create_A(value);
}
如果我没记错的话,示例代码有一个边缘情况,它不能像预期的 C++17 之前那样工作。编译器将省略 copy/move 构造函数以从 create_A()
返回的右值创建 a
。但是,它将在编译期间检查 A
的 copy/move 构造函数(它不会使用)是否为 available/accessible。从 C++17 开始,copy/move 省略完成 "properly" 并且此类代码不需要 copy/move 构造函数。 (另外,我可能记错了,它可能正在检查 copy/move 赋值。)
在 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;
}
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,但很高兴听到不那么旧的版本)
C++17 开箱即用(或借助演绎指南),以前的版本不能。
正如@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
based on your use of decltype
, though you might want to use std::decay
。
int main () {
int value = 5;
auto a = create_A(value);
}
如果我没记错的话,示例代码有一个边缘情况,它不能像预期的 C++17 之前那样工作。编译器将省略 copy/move 构造函数以从 create_A()
返回的右值创建 a
。但是,它将在编译期间检查 A
的 copy/move 构造函数(它不会使用)是否为 available/accessible。从 C++17 开始,copy/move 省略完成 "properly" 并且此类代码不需要 copy/move 构造函数。 (另外,我可能记错了,它可能正在检查 copy/move 赋值。)
在 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;
}