模板元编程参考

时间:2017-08-01 18:03:17

标签: c++ c++11 metaprogramming template-meta-programming

我正在检查第一次练习的书cpp模板元编程的一些解决方案 http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl?CPPTM_Answers_-_Exercise_2-0

  

写一个一元函数add_const_ref,如果它是a,则返回T.   引用类型,否则返回T const&

 template<typename T>
 struct add_const_ref
 {
     typedef typename boost::add_const<T>::type ct;
     typedef typename boost::add_reference<ct>::type type;
 };

我用c ++ 11修改了它:

 template<typename T>
 struct add_const_ref_type
 {
     typedef typename std::add_const<T>::type ct;
     typedef typename std::add_lvalue_reference<ct>::type type;
 };

我不明白为什么它可以参考。我希望这会添加const,即将int&更改为`const int&amp;。

 int main()
 {   
    std::cout << std::is_same<add_const_ref_type<int &>::type, int&>::value << '\n'; // print 1
    std::cout << std::is_same<add_const_ref_type<int &>::type, const int&>::value << '\n'; // print 0

    return 0;
 }

2 个答案:

答案 0 :(得分:6)

你被左侧放置类型修饰符的错误所迷惑。

const int&

我的意思是,当您将const应用于int&时,您的const int&是正确的吗?

错误。

要了解此处发生了什么,请在右侧上应用类型修饰符。修饰符总是适用于右边的东西;现在,把它放在左边&#34;是非法的:

int const&

是对const的引用。这实际上是有效的C ++。

int& const
这是胡说八道;您无法将const应用于&&本身已经不可改变;只有他们所指的内容才能改变。

当您add_const<int&>时,您从逻辑上得到int& const;特征知道这是无稽之谈,所以返回int&

现在我们退一步看看如果你把它放在左边会发生什么。如果左侧没有任何内容,则特殊规则会将其应用于最左侧。所以:

const int&

只是

int const&

using X=int&;
const X

X const

再次,左边的&#34;就在最左边的部分&#34;规则。应用此功能后,我们然后展开X

int& const

这很明显,你总是在右边应用类型修饰符,并忽略了左侧类型修饰符的特殊情况。

解决这个问题,如果你想将const添加到值类型并使引用引用const实例,很容易修改,但通常很难解决它。毕竟,引用是一种别名,指针也是如此;当你向指针添加const时,你得到一个const指针,而不是指向const的指针。

我怀疑作业要求您从头开始解决问题,而不是使用stdboost

template<class T>
struct tag_t {using type=T;};
template<class T>
struct add_const_ref:tag_t<T>{};
template<class T>
struct add_const_ref<T&>:tag_t<T const&>{};

答案 1 :(得分:3)

它起作用,因为int & const没有任何意义(引用总是const),因此std::add_const<int &>::typeint &相同。 也就是说,正在制作的部分const不是int

以下是一个例子:

#include <iostream>
#include <type_traits>

int main() {
    std::cout << std::is_same<int &, std::add_const<int &>::type>::value << std::endl;
    std::cout << std::is_same<int, std::add_const<int>::type>::value << std::endl;
    std::cout << std::is_same<int const, std::add_const<int>::type>::value << std::endl;

    std::cout << std::is_same<int &, std::add_lvalue_reference<std::add_const<int &>::type>::type>::value << std::endl;
    std::cout << std::is_same<int &, std::add_lvalue_reference<std::add_const<int>::type>::type>::value << std::endl;
    std::cout << std::is_same<int const &, std::add_lvalue_reference<std::add_const<int>::type>::type>::value << std::endl;
}

Online here