可変長引数テンプレートメンバ関数へのポインタ。その引数が期待通りにならない。
以下のC++11のコードについて
#include <iostream>
#include <tuple>
#include <utility>
#include <cxxabi.h>
#include <typeinfo>
class foo
{
public:
template<typename... types_>
void method1(types_&&... args) {
int status;
auto method2_args = std::make_tuple(
std::forward<types_>(args)...
);
auto fp = &foo::method2<int, int, decltype(method2_args)>;
std::cout << abi::__cxa_demangle(typeid(method2_args).name(), 0, 0, &status) << std::endl;
std::cout << abi::__cxa_demangle(typeid(fp).name(), 0, 0, &status) << std::endl;
// (this ->*fp)(1, 2, method2_args); // error: invalid initialization of reference of type ‘std::tuple<int, int, std::tuple<float, double> >&’ from expression of type ‘std::tuple<float, double>’
}
template<typename... types_>
void method2(int a, int b, std::tuple<types_...> &args )
{
}
};
int main()
{
foo f;
f.method1(1.0f, 2.0);
}
(this ->*fp)(1, 2, method2_args);がエラーとなってコンパイルできません。
コンパイラはg++-4.8です。g++-5.0, clang++-3.4でもエラーでした。
不思議に思い、エラー箇所をコメントアウトして、method2_argsとfpのtype_info::name()を表示させたところ
std::tuple<float, double> void (foo::*)(int, int, std::tuple<int, int, std::tuple<float, double> >&)
でした。最初のがmethod2_argsで次がfpのtype_info::name()です。
method2_argsは期待どおりでした。
しかしfpは実に奇妙で期待していたものと違いました。
void (foo::*)(int, int, std::tuple<float, double> >&)
を期待していました。
- 質問1.
fpはなぜこのような結果になるのでしょうか? - 質問2.
fpを私が期待したものにするにはどうしたらよいでしょうか?