This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to allow template function to have friend(-like) access?
How do I give function template Load friend access to class Foo?
The objective here is to restrict access to the constructor: only function template Load may construct.
CODE (please ignore memory leak)
class Foo {
Foo() { }
template<> friend Foo const& Load<Foo>(); // error here
};
template<typename T>
T const&
Load() { return *(new T); }
int main( int argc, char* argv[] )
{
Foo const& f = Load<Foo>();
}
This should work.
template<typename T> T const& Load() { return *(new T); }
class Foo {
Foo() { }
friend Foo const& Load<Foo>();
};
Doing it like this should work:
#include <iostream>
template <typename T>
const T&
load(void)
{
return *(new T);
}
class foo
{
private:
foo(void)
{
std::cout << "hello!" << std::endl;
}
template <typename T>
friend const T& load();
};
int
main(void)
{
const foo& f = load<foo>();
return 0;
}
Related
How to declare the following function as a friend of a class
template <class T>
inline auto func(T & val)
{
//return ...;
}
class A { friend auto func<A>(A & val); }
Is it legal?
Yes, you can get it to work from C++14 on.
How to do it?
You can do it like this (see here):
class A;
template <class T>
inline auto func(T& val);
class A
{
friend auto func<A>(A& val);
int j = 6;
};
template <class T>
inline auto func(T& val)
{
return val.j;
}
int main()
{
A a;
return func<A>(a);
}
However, I agree with the comments: the question could be improved if you provided an exact problem for which we could try finding an answer.
codereview would not allow hypothetical code, so I am posting here instead. Given this code:
#include <string>
struct foo {
std::string a, b;
foo (const std::string& a, const std::string& b) : a(a), b(b) { }
};
template <typename T> void bar (const T&) { }
template <typename T> void bar (T&&) { }
void execute (const foo& f) {
// etc...
bar(f.a);
// etc...
bar(f.b);
// etc...
bar(f);
// etc...
}
void execute (foo&& f) {
// etc...
bar(std::move(f.a));
// etc...
bar(std::move(f.b));
// etc...
bar(std::move(f));
// etc...
}
int main() {}
I want to write execute_helper to handle both execute overloads, since they are identical except for the std::move calls. Here is what I have, and I want to know if I did it correctly. I'm unsure about using T& and T in my check_move overloads, and whether passing T by value worsens the time complexity or not.
#include <string>
#include <iostream>
struct foo {
std::string a, b;
foo (const std::string& a, const std::string& b) : a(a), b(b) { }
};
template <typename T> void bar (const T&) { }
template <typename T> void bar (T&&) { }
template <typename T>
T check_move (const foo&, T& t) { std::cout << "std::move not called.\n"; return t; }
template <typename T>
T&& check_move (foo&&, T t) { std::cout << "std::move called.\n"; return std::move(t); }
template <typename F>
void execute_helper (F&& f) {
// etc...
bar(check_move(std::forward<F>(f), f.a));
// etc...
bar(check_move(std::forward<F>(f), f.b));
// etc...
bar(check_move(std::forward<F>(f), std::forward<F>(f)));
// etc...
}
void execute (const foo& f) {
execute_helper(f);
}
void execute (foo&& f) {
execute_helper(std::forward<foo>(f));
}
// Test
foo make_foo() {
return foo("hello", "bye");
}
int main() {
foo f("hello", "bye");
execute(f);
execute(make_foo());
}
Output:
std::move not called.
std::move not called.
std::move not called.
std::move called.
std::move called.
std::move called.
I want to explicitly instantiate template member but without instantiation of the template class. But I am getting compiler errors, so is this possible ? Here is my code:
//mytemplate.h
template <class T>
class mytemplate
{
public:
mytemplate(T* tt)
{
mT = tt;
}
template<class B>
void print(const B& bb);
T* mT;
};
//in mytemplate.cpp
#include "mytemplate.h"
template<typename T>
template<typename B>
void mytemplate<T>:: print(const B& bb)
{
B b = bb;
}
template<typename T> void mytemplate<T>::print<float>(const float&) const;
template<typename T> void mytemplate<T>::print<int>(const int&) const;
// main.cpp
int main()
{
int d =0;
mytemplate<int> k(&d);
k.print<float>(4.0);
}
With templates, it always helps to decompose the problem into the smallest possible building block. mytemplate::print can be written in terms of a call to a template free function.
This way you can achieve the effect of partial specialisation of a member function.
A leading question here is "what should the print() method do?". Here is an example in which mytemplate<T> provides a printing policy to a free function. There is no reason of course that the policy could not be some other class which has been constructed via some other (possibly specialised) template free function.
// Policy is a concept which supports 2 methods:
// print_prefix() and print_postfix()
//
template<class Policy, class B>
void print_with_policy(const Policy& policy, const B& value) const
{
policy.print_prefix();
cout << value;
policy.print_postifx();
}
template<class T>
struct mytemplate
{
// implement in terms of a free function
template<class B> void print(const B& value) {
print_with_policy(*this, value);
}
// policy concept implementation
void print_prefix() const {
cout << "prefix-";
}
void print_postfix() const {
cout << "-postfix";
}
};
extending the example to use a separate policy class with a specialisation for strings:
template<typename B>
struct default_policy {
default_policy(const B& value) : _value(value) {}
void operator()() const {
cout << "(" << _value << ")";
}
private:
const B& _value;
};
template<typename B>
struct quoted_policy {
quoted_policy(const B& value) : _value(value) {}
void operator()() const {
cout << '"' << _value << '"';
}
private:
const B& _value;
};
template<class B>
default_policy<B> make_policy(const B& value) {
return default_policy<B>(value);
}
// overload for B being a string
quoted_policy<std::string> make_policy(const std::string& value) {
return quoted_policy<std::string>(value);
}
template<class T>
struct mytemplate
{
// implement in terms of a free function
template<class B> void print(const B& value) {
make_policy(value)();
cout << endl;
}
};
int main()
{
struct foo{};
mytemplate<foo> fooplate;
fooplate.print(int(8));
fooplate.print(std::string { "a string" });
fooplate.print("not a string");
return 0;
}
output:
(8)
"a string"
(not a string)
This question already has an answer here:
How to share protected members between C++ template classes?
(1 answer)
Closed 8 years ago.
This extremely minimal example will fail to compile because A<int> cannot access the private member i in A<double>
template <class T>
class A {
int i;
public:
template <class U>
void copy_i_from( const A<U> & a ){
i = a.i;
}
};
int main(void) {
A<int> ai;
A<double> ad;
ai.copy_i_from(ad);
return 0;
}
I cannot find the correct way to make those template instances friends.
template <class T>
class A {
template<class U>
friend class A;
int i;
public:
template <class U>
void copy_i_from( const A<U> & a ){
i = a.i;
}
};
int main(void) {
A<int> ai;
A<double> ad;
ai.copy_i_from(ad);
return 0;
}
My question is related to this question.
#include<iostream>
template< typename T >
class T1 {
public:
T i;
void display()
{
std::cout<<i<<"\n"<<j<<"\n"<<k;
}
protected:
T j;
private:
T k;
friend void Test( T1 &obj);
};
template<typename T>
void Test(T1<T> &obj)
{
T a=T();
obj.i=a;
obj.j=a;
obj.k=a;
}
int main()
{
T1<int>a;
Test(a);
a.display();
}
Why doesn't the above code compile?
friend void Test( T1 &obj); declares a non template function.
Declare it as a template.
Try this :
....
private:
T k;
template<typename U>
friend void Test( T1<U> &obj);
};