Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何将从模板参数派生的编译时信息添加到模板中?_C++_Templates_C++11 - Fatal编程技术网

C++ 如何将从模板参数派生的编译时信息添加到模板中?

C++ 如何将从模板参数派生的编译时信息添加到模板中?,c++,templates,c++11,C++,Templates,C++11,我使用Stroustrup在(从23:00开始)提供的用户定义的文本处理单元实现。代码如下: #include <iostream> using std::cout; using std::endl; template<int M, int K, int S> struct Unit { // a unit in the MKS system enum {m=M,kg=K,s=S}; }; template<typename Unit&

我使用Stroustrup在(从23:00开始)提供的用户定义的文本处理单元实现。代码如下:

 #include <iostream>

 using std::cout;
 using std::endl;

 template<int M, int K, int S> 
 struct Unit { // a unit in the MKS system
   enum {m=M,kg=K,s=S}; 
 };

 template<typename Unit> // a magnitude with a unit
 struct Value {
   double val;
   constexpr Value(double d) : val(d) {}
 };

 using Meter = Unit<1,0,0>;
 using Second = Unit<0,0,1>;

 using Distance = Value< Meter >;
 using Time = Value< Second >;
 using Velocity = Value< Unit<1,0,-1> >;

 constexpr Value<Meter> operator "" _m(long double d)
 // a f-p literal with suffix 'm'
 {
   return Distance(d);
 }

 constexpr Value<Second> operator"" _s(long double d)
 // a f-p literal with suffix 's'
 {
   return Time(d);
 }

 constexpr Velocity operator/(Distance d, Time t)
 {
   return ( d.val / t.val );
 }

 int main(void)
 {
    Distance s = 100._m;
    Time t = 22._s;
    Velocity v = s/t;

    cout << "s " << s.val << "\nt " << t.val << endl;
    cout << "v " << v.val << endl;

   return 0;
 }
到目前为止还不错。现在我想向结构单元(或值?)添加一个包含单元表示的字符串。无论我想用哪种方式写作

cout << "v " << v.val << v.unit << endl;

它不需要是美丽的,因为它只是为了检查。并学习如何去做;)

当然,优雅的解决方案是在编译时对所有内容进行评估


我试过几次,但我不会让你厌烦/困惑于我的无结果尝试…

首先,我们在
值中添加
单元
成员:

 template<typename Unit> // a magnitude with a unit
 struct Value {
   double val;
   constexpr static Unit unit = {};
   constexpr Value(double d) : val(d) {}
 };
template//带单位的幅值
结构值{
双val;
constexpr静态单位={};
constexpr值(双d):val(d){
};
然后我们编写一个流输出操作符:

 template<int M, int K, int S>
 std::ostream &operator<<(std::ostream &os, Unit<M, K, S>) {
   return os << "m^" << M << " kg^" << K << " s^" << S;
 }
模板

std::ostream&operator
单元
已经有了我们需要的信息,所以我们可以通过向
添加一个函数来实现这一点,或者我们可以重载
operator@Xeo:示例代码是C++11,使用功能
用户定义的文本
constepr
。为什么不这样标记呢?因为问题的主题与此无关:)我可以构造一个不使用这些东西的示例。另外,我个人认为,如果问题的主题是c++11独有的功能,那么问题应该被标记为
[c++11]
。看起来不错。但是我得到了一个链接器错误:
对'Value::unit'的未定义引用
@steffen:因为您使用了ODR
unit
,所以需要提供一个定义<代码>模板constexpr单位值::单位值定义之后的code>应该足够了。@Xeo谢谢;按值传递stream out参数更容易。@steffen按值传递参数时,这是不必要的-我们不给它命名的事实足以表明它不会在函数中被修改。
v 4.54545 m^1 kg^0 s^-1
 template<typename Unit> // a magnitude with a unit
 struct Value {
   double val;
   constexpr static Unit unit = {};
   constexpr Value(double d) : val(d) {}
 };
 template<int M, int K, int S>
 std::ostream &operator<<(std::ostream &os, Unit<M, K, S>) {
   return os << "m^" << M << " kg^" << K << " s^" << S;
 }
template<typename U>
struct Value
{
    double val;
    constexpr Value(double d) : val(d) {}

    std::string Units() const
    {
        return "m^" + to_string(U::m) + 
               " kg^" + to_string(U::kg) +
               " s^" + to_string(U::s);
    }
};

template <typename U>
std::ostream& operator<<(std::ostream& out, Value<U> val)
{
    out << val.val
        << " m^" << U::m << " kg^" << U::kg << " s^" << U::s;
    return out;
}
template <typename U1, typename U2>
Value<Unit<U1::m - U2::m, U1::kg - U2::kg, U1::s - U2::s>>
operator/(Value<U1> v1, Value<U2> v2)
{
    return (v1.val / v2.val);
}
void demo()
{
    auto accel = Distance(100) / Time(22) / Time(1);
    cout << accel << endl; // Print with units.
    cout << accel.val << endl; // Print without units.
    cout << accel.Units() << endl; // Print only units.
}