【问题标题】:Compiler infering the template argument编译器推断模板参数
【发布时间】:2020-02-15 12:33:37
【问题描述】:
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


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      正如@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));
      }
      

      根据您对decltype 的使用,我使用了std::remove_reference,但您可能想改用std::decay

      int main () {
        int value = 5;
        auto a = create_A(value);
      }
      

      如果我没记错的话,示例代码有一个边缘情况,它不能按 C++17 之前的预期工作。编译器将省略复制/移动构造函数以从create_A() 返回的右值创建a。但是,它会在编译期间检查A 的复制/移动构造函数(它不会使用)是否可用/可访问。从 C++17 开始,复制/移动省略是“正确”完成的,此类代码不需要复制/移动构造函数。 (另外,我可能记错了,它可能正在检查复制/移动分配。)

      【讨论】:

      • 如果我没记错的话,不能保证在 C++17 之前省略复制/移动
      【解决方案3】:

      在 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;
      }
      

      Demo

      【讨论】:

        猜你喜欢
        • 2020-01-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-09
        • 1970-01-01
        • 2017-06-16
        • 2014-11-20
        • 2010-10-17
        相关资源
        最近更新 更多