【问题标题】:When a compiler can infer a template parameter?编译器何时可以推断模板参数?
【发布时间】:2009-04-28 12:21:11
【问题描述】:

有时有效,有时无效:

template <class T> 
void f(T t) {}

template <class T>
class MyClass {
public:
  MyClass(T t) {}
};

void test () {
  f<int>(5);
  MyClass<int> mc(5);
  f(5);
  MyClass mc(5); // this doesn't work
}

有没有办法破解上面的例子? IE。强制编译器从构造函数参数推断模板参数。

这个问题会在未来得到解决,还是有充分的理由不解决?

编译器可以推断模板参数的一般规则是什么?

【问题讨论】:

    标签: c++ templates


    【解决方案1】:

    当可以从模板参数中推断出参数类型时,可以为函数模板推断模板参数

    所以可以在这里推断:

    template <typename T>
    void f(T t);
    
    template <typename T>
    void f(std::vector<T> v);
    

    但不在这里:

    template <typename T>
    T f() {
      return T();
    }
    

    而不是在类模板中

    所以你的问题通常的解决方案是创建一个包装函数,类似于标准库函数std::make_pair

      template <class T>
        class MyClass {
        public:
            MyClass(T t) {}
            void print(){
                std::cout<<"try MyClass"<<std::endl;
            }
        };
    
        template <typename T>
        MyClass<T> MakeMyClass(T t) { return MyClass<T>(t); }
    

    然后调用auto a = MakeMyClass(5); 实例化该类。

    【讨论】:

    • +1,彻底。次要问题:我建议将“参数类型依赖时”更改为“参数类型依赖时”。
    • void f(typename T::const_iterator t); ::const_iterator 调用它,它也无法为T 推导出vector。原因是::const_iterator 的含义取决于T。但T 又取决于关于 ::const_iterator 的含义。这就是为什么 boost::implicit_cast 编码如下: template T implicit_cast(typename identity::type t) { return t; } 再次,我们有一个不可推断的上下文。
    • Standard-ref 是 14.8.2.4/4(最新的 c++1x 草案位于 14.9.2.5/5 - 还修复了当前标准中措辞的一些缺点)。 :) 干杯
    • 呃,你是对的,当然。不知道我在想什么。
    • 这个答案现在已经过时了。可以推断类模板参数in C++17
    【解决方案2】:

    【讨论】:

    • 这是一个仅链接的答案,请考虑通过提供参考材料中的相关信息来改进此答案。
    【解决方案3】:

    从C++20开始,可以infer the types of function parameters使用auto

    #include <iostream> 
    #include <string>
    
    auto print_stuff(auto x, auto y) 
    { 
        std::cout << x << std::endl;
        std::cout << y << std::endl;
    }
    
    int main() 
    { 
        print_stuff(3,"Hello!");
        print_stuff("Hello!",4);
        return 0; 
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-01-21
      • 1970-01-01
      • 1970-01-01
      • 2014-11-20
      • 2013-12-09
      • 2015-03-13
      • 1970-01-01
      相关资源
      最近更新 更多