【问题标题】:What is the deduced type of a constexpr?constexpr 的推导类型是什么?
【发布时间】:2016-10-21 12:22:43
【问题描述】:
#include <iostream>
#include <string>

void foo(int& k) { std::cout << "int&\n"; }
void foo(int&& k) { std::cout << "int&&\n"; }
void foo(const int& k) { std::cout << "const int&\n"; }
void foo(const int&& k) { std::cout << "const int&&\n"; }    
int main() {
  static  constexpr int k = 1;
  foo(k);
  foo(1);
}

输出是:

const int&
int&&

constexpr 变量究竟被视为什么? foo 的重载为 const int&amp;

编辑:继续将 constexpr 推导出为 const T&amp;;

为什么类范围内的 constexpr 无法传递给采用通用引用的函数?!

#include <type_traits>

template <typename T>
void goo(T&& k) {
  static_assert(std::is_same<decltype(k), const int&>::value, "k is const int&");
}

class F {
  static  constexpr int k = 1;
public:
  void kk2 () { goo(k); }
};

int main () {
  F a;
  a.kk2();
}

以上编译失败,报错undefined reference to F::k 但是以下通过:

#include <type_traits>

template <typename T>
void goo(T&& k) {
  static_assert(std::is_same<decltype(k), const int&>::value, "k is const int&");
}

int main() {
  static  constexpr int k = 1;
  goo(k);
}

【问题讨论】:

  • @GuillaumeRacicot 我认为这句话是指goo(T&amp;&amp; k)

标签: c++ c++11 templates overloading constexpr


【解决方案1】:

N3337 [dcl.constexpr]/9: 对象声明中使用的constexpr 说明符将对象声明为const。 [...]

由于您将k 声明为constexpr,因此它也声明为const,因此在重载决议中选择了const int&amp;

【讨论】:

    【解决方案2】:
    foo(1);
    

    在这种情况下,一个值为 1 的临时变量被传递给函数 foo,因此是非 const 右值。

    /*static*/ constexpr int k = 1;
    foo(k);
    

    这里一个名为 const 变量的值为 1 被传递给函数 foo,因此是 const lvalue。 static 关键字对函数范围内的 constexpr 变量没有影响。

    constexpr 变量究竟被视为什么?

    当在不是常量表达式的表达式中使用时,constexpr 变量只是一个const 变量。

    为什么类范围内的 constexpr 无法传递给采用通用引用的函数?!

    您收到链接器错误,因为您在未定义变量的情况下使用了该变量。您需要在命名空间范围内精确地在一个翻译单元中定义 F::k,就像您在 C++98 中为 static const 成员变量所做的那样。

    【讨论】:

      猜你喜欢
      • 2018-02-18
      • 2022-01-03
      • 2016-08-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-14
      • 2022-11-16
      相关资源
      最近更新 更多