C++ 为什么在运行时调用这个rvalue constexpr构造函数?
为什么下面的代码会在前两种情况下将类A的用法视为constexpr,而在第三种情况下则不会?我在4.9到7.1的不同版本的gcc中尝试过这一点,每次都体验到相同的行为。我错过了什么C++ 为什么在运行时调用这个rvalue constexpr构造函数?,c++,constexpr,C++,Constexpr,为什么下面的代码会在前两种情况下将类A的用法视为constexpr,而在第三种情况下则不会?我在4.9到7.1的不同版本的gcc中尝试过这一点,每次都体验到相同的行为。我错过了什么 template <std::size_t N> struct B{}; class A { public: constexpr A(std::size_t value):value_(value){} std::size_t const value_; }; std::int32_
template <std::size_t N> struct B{};
class A
{
public:
constexpr A(std::size_t value):value_(value){}
std::size_t const value_;
};
std::int32_t main
(
std::int32_t,
char const **
)
{
A a(1); // expected - constructor not invoked at run time
B<A(1).value_> b; // expected - compiles so clearly constexpr
A(1); // *** unexpected *** - invokes the constructor at run time, why?
return 0;
}
模板结构B{};
甲级
{
公众:
constexpr A(std::size\u t value):value(value){
标准::尺寸常数值;
};
std::int32\u t main
(
std::int32_t,
字符常数**
)
{
A(1);//在运行时未调用预期的-constructor
B;//expected-编译得非常清楚constexpr
A(1);//***意外***-在运行时调用构造函数,为什么?
返回0;
}
更新了更全面的示例
template <std::size_t N>
struct B
{
constexpr std::size_t dont_optimize_me_out
(
)
{
return 0;
}
};
constexpr std::size_t some_hash
(
char const *,
std::size_t
)
{
return 0;
}
class hashed_id
{
public:
template <std::size_t N>
constexpr hashed_id
(
char const (&input)[N]
):
value_(some_hash(input, N - 1))
{
}
constexpr hashed_id
(
std::size_t value
):
value_(value)
{
}
constexpr std::size_t get_value
(
)
{
return value_;
}
private:
std::size_t const value_;
};
class A
{
public:
constexpr A
(
hashed_id id
):
id_(id)
{
}
constexpr hashed_id get_id
(
)
{
return id_;
}
constexpr std::size_t dont_optimize_me_out
(
)
{
return id_.get_value();
}
private:
hashed_id const id_;
};
int main
(
int,
char const **
)
{
std::size_t k = 0;
A a("foo"); // expected - constructor not invoked at run time
k += a.dont_optimize_me_out();
B<A("foo").dont_optimize_me_out()> b; // expected - compiles so clearly constexpr
k += b.dont_optimize_me_out();
k += A("foo").dont_optimize_me_out(); // *** unexpected *** - invokes the constructor (and hash function) at run time, why?
std::cout << k << std::endl;
return 0;
}
模板
结构B
{
constexpr标准::大小\u t\u优化\u me\u
(
)
{
返回0;
}
};
constexpr std::size\u t一些散列
(
字符常量*,
标准:尺寸
)
{
返回0;
}
类散列id
{
公众:
模板
constexpr散列\u id
(
字符常量(和输入)[N]
):
值(一些散列(输入,N-1))
{
}
constexpr散列\u id
(
标准::大小\u t值
):
价值(价值)
{
}
constexpr std::size\u t get\u值
(
)
{
返回值;
}
私人:
标准::尺寸常数值;
};
甲级
{
公众:
constexpr A
(
散列id
):
身份证(身份证)
{
}
constexpr散列\u id获取\u id
(
)
{
返回id_u2;;
}
constexpr标准::大小\u t\u优化\u me\u
(
)
{
返回id_u.get_值();
}
私人:
散列id常量id;
};
int main
(
int,
字符常数**
)
{
标准:尺寸k=0;
A(“foo”);//预期-在运行时未调用构造函数
k+=a.不要优化我自己();
B;//expected-编译得非常清楚constexpr
k+=b.不要优化我自己();
k+=A(“foo”)。dont_optimize_me_out();//***意外***-在运行时调用构造函数(和哈希函数),为什么?
std::cout[OT]这是main
的一个有趣的签名。不确定它是否违反了标准,因为int
不必与int32\t
@NathanOliver相同:这是一个违反。3.6.1[basic.start.main]声明,main
“应具有int
类型的声明返回类型。”@IInspectable这是否意味着它在所有情况下都是非法的,还是仅仅当int32\u t
不是int
时?就像是使用bar=int;bar main(){}
非标准?@NathanOliver:它说的是“类型int
的声明返回类型”,所以我想除了int
之外的任何东西都是违反规定的。@IInspectable有道理。谢谢。