我遇到一個錯誤,當使用模板類型演繹結合C++ 14 std ::得到<>與類型索引。代碼可能看起來有點複雜,但我試圖將其簡化爲對正在發生的事情的基本知識。它實際上只是一個Observer模式...結構'A'允許根據消息類型(M1,M2,...)設置觀察者。請注意,每個消息類型只有一個觀察者,爲了簡單起見。C++ 14元組類型索引失敗推斷類型從std :: bind我想成爲std :: function
現在,技巧(以及失敗的部分)正在使用C++ 14的std :: get <>,它允許您使用實際類型索引到唯一類型的元組。下面是一個簡單的例子證明了我的意思:
void sample()
{
std::tuple<int, float> myTuple;
std::get<float>(myTuple) = 3.141f; // C++14 allows this
std::get<1>(myTuple) = 3.141f; // C++11 way to do it, using index
}
考慮到這一點,這是我的節目(從上面的代碼分開)不編譯,因爲C++ 14元組類型的索引上的失敗推斷類型:
#include <cxxabi.h>
#include <stdlib.h>
#include <functional>
#include <vector>
#include <tuple>
#include <typeinfo>
#include <iostream>
#include <string>
// ===================================
// A quick'n'dirty way to print types (nonportable)
// And yes, I know this code could be improved :)
inline
std::string demangle(char const *mangled)
{
char *output = (char *)malloc(16384);
size_t length = 16384;
int status;
__cxxabiv1::__cxa_demangle(mangled, output, &length, &status);
std::string s(output, length);
free(output);
return s;
}
#define DEMANGLE(T) demangle(typeid(T).name())
// ===================================
struct A
{
struct M1
{};
struct M2
{};
using Tuple = std::tuple<
std::function<void(M1 const &)>
,std::function<void(M2 const &)>
>;
template<typename T>
void setObserver(T func)
{
// This works fine
std::cout << DEMANGLE(T) << std::endl;
// ************************************************
// The line below does not compile (std::get fails)
//
// Note the type of T prints out as:
// std::_Bind<std::_Mem_fn<void (B::*)(A::M1 const&)> (B*, std::_Placeholder<1>)>
//
// Rather than the (desired):
// std::function<void (A::M1 const&)>(A::M1 const&)> (B*, std::_Placeholder<1>)>
//
// ************************************************
std::get<T>(tuple_) = func; // C++14 only
}
private:
Tuple tuple_;
};
// ===================================
struct B
{
void func(A::M1 const &)
{}
};
// ===================================
int main()
{
A *a = new A;
B *b = new B;
using namespace std::placeholders;
a->addObserver(std::bind(&B::func, b, _1));
return 0;
}
UPDATE:
提出的解決方案不能解決問題,從性病::綁定(...)轉換爲標準::函數(...)的問題,但它需要我爲我的每個類型M1,M2,...,
0123都有一個單獨的setObserver()函數我該如何模板化setObserver()來解決這個問題?
我試圖避免每個M1,M2,都有一個單獨的setObserver()函數......這就是爲什麼我模板化的東西。有沒有辦法只有一個setObsrver()模板函數,而不是一個用於M1和一個用於M2? – user5406764
@ user5406764 - 查看我的更新 – PiotrNycz