試着追蹤返回類型和標籤調度,我寫了下面的代碼。追尾返回類型和標籤調度
#include <string>
#include <iostream>
using namespace std;
namespace Params
{
struct t_param1{};
struct t_param2{};
};
template<typename t_detail>
struct Select;
template<>
struct Select<Params::t_param1> {using choice = Params::t_param1;};
template<>
struct Select<Params::t_param2> {using choice = Params::t_param2;};
class Tester
{
private:
using t_uint32 = uint32_t;
using t_string = string;
private:
t_uint32 m_param1;
// t_string m_param2;
private:
template<typename t_entity>
void assign(const Params::t_param1&, t_entity&& entity);
template<typename t_entity>
void assign(const Params::t_param2&, t_entity&& entity);
auto access(const Params::t_param1&) -> decltype(m_param1);
// auto access(const Params::t_param2&) -> decltype(m_param2);
public:
template<typename t_detail, typename t_entity>
void assign(t_entity&& entity);
template<typename t_detail>
auto access() -> decltype(access(typename Select<t_detail>::choice()));
};
template<typename t_detail, typename t_entity>
void
Tester::assign(t_entity&& entity)
{
assign(typename Select<t_detail>::choice(), entity);
}
template<typename t_entity>
void
Tester::assign(const Params::t_param1&, t_entity&& entity)
{
m_param1 = entity;
cout << "Assigned m_param1 with " << entity << endl;
}
/*
template<typename t_entity>
void
Tester::assign(const Params::t_param2&, t_entity&& entity)
{
m_param2 = entity;
cout << "Assigned m_param2 with " << entity << endl;
}
*/
template<typename t_detail>
auto
Tester::access()
-> decltype(access(typename Select<t_detail>::choice()))
{
return(access(typename Select<t_detail>::choice()));
}
auto
Tester::access(const Params::t_param1&)
-> decltype(m_param1)
{
return(m_param1);
}
/*
auto
Tester::access(const Params::t_param2&)
-> decltype(m_param2)
{
return(m_param2);
}
*/
int main() {
auto tester = Tester();
tester.assign<Params::t_param1>(79);
// tester.assign<Params::t_param2>("viziv");
auto param1 = tester.access<Params::t_param1>();
// auto param2 = tester.access<Params::t_param2>();
cout << "Access: param1 = " << param1 << endl;
// cout << "Access: param2 = " << param2 << endl;
return 0;
}
當我編譯使用蘋果的LLVM版本7.0.2(鐺-700.1.81)這段代碼中,我得到以下編譯錯誤
junk1.cpp:78:9: error: out-of-line definition of 'access' does not match any declaration in 'Tester'
Tester::access()
^~~~~~
1 error generated.
奇怪的是,當我取消註釋代碼分配和訪問param2(在上面的代碼中註釋掉),它編譯得很好併產生所需的結果。
我在做什麼錯?任何人都可以向我解釋爲什麼在編譯行爲中包含param2變化?
嗯...不確定。如果將問題函數的定義移動到類定義中,似乎可行,但我無法解釋_why_解決了問題。請參閱http://ideone.com/1XMZrN。 ......如果我們使用'decltype(auto)'作爲問題函數的返回類型,即使定義不在類定義之外,也沒有尾隨返回類型,它似乎也能工作。 –
這是一個_minimal_ reproducer嗎? –
@PreferenceBean我這麼認爲。我只有兩個公共成員可以分配和一個訪問,而私有函數實現標籤分派。 – vixiv