I have some code snippets like below,
struct stA
{
struct stB
{
void func() const { std::cout << "const" << std::endl; }
void func() { std::cout << "non-cont" << std::endl; }
};
};
template <typename T>
void test()
{
typename T::stB b;//can I get a const version of b?
b.func();
/*...*/
}
In my test, I found I can't get a const version of b
even if I instantiated this function template test
with T = const stA
argument.
So the question is can I get a const dependent name when instantiating a template?
If the answer is NO, I also want to know why qualifier const
is discarded when substituting the template argument?
If the answer is YES, I want to HOW?
BTW, I tested above code in VS2017.
typename T::stB b;//can I get a const version of b?
Sure. Use a helper class to select the type.
#include <iostream>
struct stA
{
struct stB
{
void func() const
{
std::cout << "const" << std::endl;
}
void func()
{
std::cout << "non-cont" << std::endl;
}
};
};
// Helper class to select the type.
// Base version provides a non-const type.
template <typename T> struct type_selector
{
using type = typename T::stB;
};
// Specialization provides a const type.
template <typename T> struct type_selector<const T>
{
using type = const typename T::stB;
};
template <typename T>
void test()
{
typename type_selector<T>::type b;
b.func();
}
int main()
{
test<stA>();
test<const stA>();
}
Output:
non-cont
const
As alternative, using existing traits:
template <typename T>
void test()
{
typename std::conditional<std::is_const<T>::value,
const typename T::stB,
typename T::stB>::type b;
b.func();
/*...*/
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.