c ++:编译器推断出模板参数?

问题描述 投票:0回答:4
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++ templates compilation decltype declval
4个回答
4
投票

C ++ 17开箱即用(或借助演绎指南),以前的版本则不能。


3
投票

正如@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的使用而使用了std::remove_reference,尽管您可能想改用decltype

std::decay

如果我没记错的话,示例代码有一个极端的情况,即在C ++ 17之前无法正常工作。编译器将取消复制/移动构造函数,以从std::decay返回的右值创建int main () { int value = 5; auto a = create_A(value); } 。但是,它将在编译期间检查a的复制/移动构造函数(它将不使用)是否可用/可访问。从C ++ 17开始,复制/移动省略是“适当地”完成的,此类代码不需要复制/移动构造函数。 (此外,我可能记错了,它可能正在检查复制/移动分配。)


0
投票

在C ++ 17及更高版本中,您可以添加推导指南。

create_A()

但是在这种简单情况下,C ++ 17甚至不需要。


0
投票

在C ++ 11中,您可以创建一个简单的A函数,如下所示:

template<typename T>
A(T&) -> A<T>;

make_A

© www.soinside.com 2019 - 2024. All rights reserved.