为什么通过显式构造函数来提升整数?

5

This code

#include <cstdint>

constexpr uint32_t ticksPerSecond = 100000;

struct timemeasure {
    constexpr explicit timemeasure(uint64_t c) : ticks(c) { }
    uint64_t ticks;
    constexpr timemeasure() : ticks(0) { }
};

struct time : timemeasure {
    static volatile time now;

    constexpr time() : timemeasure() { }
    explicit time(uint64_t c) : timemeasure(c) { }

    // Needed for `x = time::now`
    explicit time(const volatile time &t) : timemeasure(t.ticks) { }
    time& operator=(volatile time t) { ticks = t.ticks; return *this; }
};

inline time foo(const time& t) { return time(t.ticks + 1); }

编译错误提示:

prog.cpp: In function ‘time foo(const time&)’:
prog.cpp:22:57: error: no matching function for call to ‘time::time(time)’
prog.cpp:22:57: note: candidate is:
prog.cpp:14:15: note: constexpr time::time()
prog.cpp:14:15: note:   candidate expects 0 arguments, 1 provided

为什么要调用time::time(time)uint64_t肯定不能被提升吧?

为什么示例中都要使用 volatile 关键字?是因为 now 变量会被多个线程更新吗? - Casey
@Casey:它由一个线程更新,被其他线程读取。 - Eric
C++11是一个选项吗?使用std::atomic来处理now将避免所有与易失性副本和赋值运算符有关的混乱(像这样)。 - Casey
@Casey:我正在使用C++11,但我不确定std::atomic在中断处理程序的上下文中是否有效。 - Eric
让我们在聊天中继续这个讨论:http://chat.stackoverflow.com/rooms/32095/discussion-between-casey-and-eric - Casey
显示剩余2条评论
2个回答

7
< p > < code >时间的复制构造函数被标记为explicit,在从函数返回值时,临时对象将从该值进行复制初始化。 C++11标准的第8.5/15段规定:

The initialization that occurs in the form

T x = a;

as well as in argument passing, function return, throwing an exception (15.1), handling an exception (15.3), and aggregate member initialization (8.5.1) is called copy-initialization. [...]

然而,被标记为explicit的构造函数在复制初始化的上下文中不被考虑(请参见13.3.1.4/1和13.3.1.5/1),因此出现了错误。


我自己刚刚得出了这个结论。 - Eric
@Eric:我知道那种感觉,向他人提问往往是 真正 向自己提问的最佳方式 ;) - Andy Prowl
答案对原因是正确的,但在论证上失败了。问题不在于接受 uint64_t 的构造函数,在代码中该构造函数被显式地调用。问题出在复制构造函数被声明为 explicit - David Rodríguez - dribeas
@DavidRodrГӯguez-dribeasпјҡжІЎй”ҷпјҢдёҚиҝҮеҪ“жҲ‘ејҖе§Ӣеӣһзӯ”ж—¶пјҢй—®йўҳдёӯзҡ„д»Јз ҒеҢ…еҗ«еҸҰдёҖдёӘиҝ”еӣһзұ»еһӢдёәuint64_tзҡ„еҮҪж•°xпјҲеҮҪж•°зҡ„иҝ”еӣһзұ»еһӢжҳҜtimeпјүгҖӮжҲ‘жІЎжңүзңӢеҲ°жӣҙж–°гҖӮж— и®әеҰӮдҪ•пјҢжҲ‘е·Із»Ҹзј–иҫ‘дәҶзӯ”жЎҲпјҢи°ўи°ў :) - Andy Prowl

0

你不能从 foo 中按值返回 time,因为 time 没有可访问的复制构造函数:从 volatile const time& 构造函数不匹配。加入一个:

time(const time&) = default;

1
它会匹配,但因为它是“显式”的,所以不会被检查。 - aschepler
根据gcc 4.7.2的说法,@aschepler是错误的:no known conversion for argument 1 from ‘time’ to ‘const volatile time&’ - Casey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接