C++ Extensions for Library Fundamentals、バージョン 2 ( N4564 ) では type が導入されていstd::experimental::source_location
ます。
§ 14.1.2 [reflection.src_loc.creation] は次のように述べています。
static constexpr source_location current() noexcept;
戻り値: postfix-expressionが (括弧で囲まれている可能性がある) id-expression Namingである関数呼び出し (C++14 § 5.2.2) によって呼び出されると、実装定義の値を持つ を
current
返します。source_location
値は、 および と#line
同じ方法で (C++14 § 16.4) の影響を受ける必要が__LINE__
あり__FILE__
ます。他の方法で呼び出された場合、返される値は規定されていません。備考:ブレースまたはイコール初期化子を使用して非静的データ メンバーを初期化する場合、すべての呼び出しは、
current
メンバーを初期化するコンストラクターまたは集約の初期化の場所に対応する必要があります。[注:デフォルトの引数 (C++14 § 8.3.6) として使用される場合、の値は呼び出しサイトでの呼び出し
source_location
の場所になりcurrent
ます。—エンドノート]
私の理解が正しければ、この機能はこのように使用されることを意図しています。
#include <experimental/source_location> // I don't actually have this header
#include <iostream>
#include <string>
#include <utility>
struct my_exception
{
std::string message {};
std::experimental::source_location location {};
my_exception(std::string msg,
std::experimental::source_location loc = std::experimental::source_location::current()) :
message {std::move(msg)},
location {std::move(loc)}
{
}
};
int
do_stuff(const int a, const int b)
{
if (a > b)
throw my_exception {"a > b"}; // line 25 of file main.cxx
return b - a;
}
int
main()
{
try
{
std::cout << do_stuff(2, 1) << "\n";
}
catch (const my_exception& e)
{
std::cerr << e.location.file_name() << ":" << e.location.line() << ": "
<< "error: " << e.message << "\n";
}
}
期待される出力:
main.cxx:25: error: a > b
がなければ、例外オブジェクトを適切に初期化するためにおよびマクロを内部的にstd::experimental::source_location
使用するヘルパー マクロを使用した可能性があります。THROW_WITH_SOURCE_LOCATION
__FILE__
__LINE__
ライブラリがどのように実装できるのか疑問に思っていましたstd::experimental::source_location
。私が要点を完全に見逃していない限り、そうするのは特別なコンパイラ サポートなしでは不可能です。しかし、これを機能させるには、どのような魔法のコンパイラ機能が必要でしょうか? に展開されたトリックに匹敵しstd::initializer_list
ますか?この機能の実験的な実装はありますか? GCC の SVN ソースを確認しましたが、まだ何も見つかりませんでした。