如何返回对非类型模板参数

时间:2018-01-17 18:45:10

标签: c++

我已就此做了大量研究,但我无法找到解决问题的设计模式。这是对我尝试执行的操作的最小描述。

#include <iostream>
using namespace std;

template <class T, T default_value=T{}>
class A{
private:
       T inclassValue;
public:
       A(T icv):inclassValue{icv}{}       

       const T& operator[](int k){
          if(k==1) return inclassValue;
       return default_value; 
       }
};

struct two_int{int x;int y;};

int main(){
    A<int> a{4};
    cout << "a[0]=" << a[0] << endl;
    cout << "a[1]=" << a[1] << endl;
    /*
    A<two_int> b{{3,5}};
    cout << "b[0]=" << b[0].x << "," << b[0].y  << endl;
    cout << "b[1]=" << b[1].x << "," << b[1].y  << endl;
    */
    return 0;

}

代码将按预期编译,链接和输出

a[0]=0
a[1]=4

编译器抱怨但是对使用default_value的代码行发出警告

return default_value;//Returning reference to local temporary object

这有点道理。取消注释main和编译的最后一部分,编译器在构建模板时发出错误

template <class T,  const T default_value= T{}>//A non-type template parameter cannot have type 'two_int'

虽然我理想的是希望

b[0]=0,0
b[1]=3,5

我能够通过添加一个额外的辅助类来提出解决方案,它将为模板参数提供T的default_value(作为静态成员)。我不相信我的技巧的稳健性,我想知道是否存在解决这个问题的设计模式。类型警告和非类型错误。另外,我要补充一点,我的主要目标是能够随意提供default_value(例如6为int而不是0)。

谢谢

2 个答案:

答案 0 :(得分:0)

不完全确定您要查找的内容,但是创建静态默认T的静态帮助程序可能很有用:

template <typename T>
static const T& default_value() {
  static const T* t = new T{};
  return *t;
}

请注意,即使跨越线程(在c ++ 11中)也会构造一次T,但仍然永远不会破坏T.因为它是静态的,所以可能缺少破坏是可以接受的,但这当然取决于T. / p>

答案 1 :(得分:0)

这是一个版本,它将参数转发给存储为constexpr的default_value的构造函数。你在这里作为参数有效传递的内容非常有限(不确定究竟有多少),所以它将取决于你的用例。

#include <iostream>
using namespace std;

template <class T, auto... Args>
class A{
private:
       T inclassValue;
       constexpr static T default_val = T{Args...}; // Changed to curly brackets here
public:
       constexpr A(T icv):inclassValue{icv}{}       

       const T& operator[](int k){
          if(k==1) return inclassValue;
       return default_val; 
       }
};

struct two_int{int x;int y;};

int main(){
    A<int> a{4};
    cout << "a[0]=" << a[0] << endl;
    cout << "a[1]=" << a[1] << endl;

    A<two_int> b{{3,5}};
    cout << "b[0]=" << b[0].x << "," << b[0].y  << endl;
    cout << "b[1]=" << b[1].x << "," << b[1].y  << endl;

    return 0;
}